Thread: for loop inquiry

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    271

    for loop inquiry

    I was writing a program which accepted an integer value, than picked out each number at each decimal value, checked if that was a multiple of 3, and if it was, added it all up.

    First, here's the code I wrote:

    Code:
    #include <stdio.h>
    
    int i_summultofthree(int i)
    {
     int sum; char s[256];
     sum = 0;
     sprintf(s, "%d", i);
     for(i=0;s[i]==0; i++)
     {
      if(s[i]%3 == 0)
      {
       i = s[i] - 48;
       sum = sum + i;
      }
     }
     return sum;
    }
    
    void main()
    {
     int i;
     i = 123456789;
     printf("%d\n", i_summultofthree(i));
    }
    I used Visual Studio 2003 to compile the above (overkill, I know. But I could get it cheap so I might as well use it).

    The problem is, "s[i]==0" is not returning any statements at all so the entire loop spins round and round infinitely.

    I can make the above code work if I simply change the conditional to "s[i] > 0", but I'm curious why the conditional is not working as it is.

    I've also tried

    Code:
    s[i] == '\0'
    and changing the sprintf to
    Code:
     sprintf(s, "%d\0", i);
    None of it works except "s[i]>0".

    Can somebody tell me why?

  2. #2
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Because the middle condition of a for loop needs to be true for the loop to continue. You want to loop UNTIL s[i]==0, so your condition should be the opposite: s[i]!=0, or simply s[i], since non-zero is implicitly true.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Stupid me.

    I posted the wrong thing.

    Actually, neither s[i]!=0 nor s[i]!='\0' are working.

  4. #4
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    It's not working because S[i] is 0 at the start, there for it's not going into the loop at all and it's returning sum as it's initialized value.

    With the code as it is, I'm getting a return of 0. If you change the value of sum, you'll get a return of that. Leave the code as it is and put a printf() statement into the loop, it won't ever print it.

    Also for loops escape when the middle condition is met. It'll loop when the condition isn't true, not the other way around.
    Last edited by SlyMaelstrom; 10-20-2005 at 09:51 PM.
    Sent from my iPadŽ

  5. #5
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Are you sure? It works fine for me.

    My code (with a printf for debugging):
    Code:
    #include <stdio.h>
    
    int i_summultofthree(int i)
    {
     int sum; char s[256];
     sum = 0;
     sprintf(s, "%d", i);
     for(i=0;s[i]!=0; i++)
     {
      if(s[i]%3 == 0)
      {
          printf("found %c to be divisible by 3, summing\n", s[i]);
       i = s[i] - '0';
       sum = sum + i;
      }
     }
     return sum;
    }
    
    int main()
    {
     int i;
     i = 123456789;
     printf("%d\n", i_summultofthree(i));
     return 0;
    }
    My output:
    Code:
    found 3 to be divisible by 3, summing
    found 6 to be divisible by 3, summing
    found 9 to be divisible by 3, summing
    18
    Notice also that I have changed 48 to '0'. Using 48 doesn't buy you anything, and renders your code dependent on the ASCII character set. The compiler will translate '0' to the correct value for your character set anyway, and it's easier to understand.

    Also, main needs to return int, I have fixed this.

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Um, in my compiler, it's just going through an infinite loop.

  7. #7
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    You're using identical code to what I pasted? If not, please paste your code, I doubt it's the compiler. Not that I implicitly trust a Microsoft compiler, but it shouldn't mess up on such a simpler program.

  8. #8
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Actually, I just copy/pasted your code into my IDE and it's going through an infinite loop.

  9. #9
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Where is the infinite loop? Put some printf's in to inspect the variables (i and s[i]), what is happening to i, is it incrementing?

    If the code I pasted does indeed result in an infinite loop, suggest you report a bug. Maybe I didn't get enough sleep last night and I'm missing an error in your code that is resulting in undefined behaviour, though.

  10. #10
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    You have a very unique problem, then.

    As CRW said, just print the value of i in the loop. If you're getting an endless stream of incrementing numbers, then you got some sort of bug.

    Here is my output when printing "i" in the loop of his code.

    Code:
    0
    1
    2
    found 3 to be divisible by 3, summing
    4
    5
    found 6 to be divisible by 3, summing
    7
    8
    found 9 to be divisible by 3, summing
    10
    18
    Last edited by SlyMaelstrom; 10-20-2005 at 10:05 PM.
    Sent from my iPadŽ

  11. #11
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    One other point, technically you shouldn't expect 123456789 to fit into an int type. Although int is at least 32 bits on all modern systems, it can be as small as 16 bits. You should use a long type and %ld. I assume and hope sizeof(int) is 4 on Visual Studio?

    Check the char array "s" with a printf after your sprintf?
    Last edited by cwr; 10-20-2005 at 10:12 PM.

  12. #12
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Thanks for all the feedback.

    I wanted to prove to you that I was getting an infinite loop, so I copied the code, then added a few lines so that I would have text output.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int i_summultofthree(int i)
    {
    	FILE* f;
    	f = fopen("c:\test.txt", "w");
     int sum; char s[256], s2[256];
     sum = 0;
     sprintf(s, "%d", i);
     for(i=0;s[i]!=0; i++)
     {
      if(s[i]%3 == 0)
      {
          printf("found %c to be divisible by 3, summing\n", s[i]);
    	  fprintf(f, "found %c to be divisible by 3, summing\n", s[i]);	  
       i = s[i] - '0';
       sum = sum + i;
      }
     }
     fclose(f);
     return sum;
    }
    
    int main()
    {
     int i;
     i = 123456789;
     printf("%d\n", i_summultofthree(i));
     return 0;
    }
    Call me a monkey's uncle, but the above code simply crashes.

    I'm new to C so please forgive me if I coded it wrong above, but I think there's nothing fundametally wrong with it.

  13. #13
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    To the integer question, yes it is. The upper limit is 2 billion or thereabouts.

  14. #14
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    cunnus88, well that's nothing like the code I pasted.

    For a start, you're opening a file, and you're not checking the return of fopen. fopen on "c:\test" will be interpreted as c:<TAB CHARACTER>est because of the \t. Use a double backslash (\\) or use a /, either will work. And check that fopen succeeded.

    Edit:

    That said, it doesn't affect the code, still doesn't produce any infinite loop. Are you sure you're pasting all the relevant code?

    Edit again:

    Oh, except that you will be fprintf'ing to a NULL pointer, since the fopen will have failed. That will likely crash your program.

  15. #15
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    First, I tried printf with the s, and it outputs on the console as 123456789, perfectly fine.

    Next, as you can see from the code I posted here, my code is a perfect replica of yours (except for the file IO portion).

    And to prove, it i've attached the text output (which I obtained after correcting the code according to your instructions).

    I had to escape with ctrl-c in the middle and lop off the text file a bit because it exceeded 500KB but i guess it's the same thing.
    Last edited by cunnus88; 02-04-2008 at 01:12 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. GNU strip inquiry
    By Chris87 in forum Tech Board
    Replies: 2
    Last Post: 07-05-2009, 08:04 PM
  2. Bitflags inquiry
    By Chris87 in forum C Programming
    Replies: 4
    Last Post: 01-03-2009, 06:22 PM
  3. Teaching myself C, quick inquiry
    By Iconate in forum C Programming
    Replies: 2
    Last Post: 02-24-2008, 03:19 PM
  4. Loops: The 'any' inquiry
    By chubbs1900 in forum C++ Programming
    Replies: 6
    Last Post: 12-10-2007, 10:35 AM
  5. inquiry from a hungry mac os x user
    By terabyter in forum C Programming
    Replies: 3
    Last Post: 06-23-2006, 09:04 AM