-
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
and changing the sprintf to
Code:
sprintf(s, "%d\0", i);
None of it works except "s[i]>0".
Can somebody tell me why?
-
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.
-
Stupid me.
I posted the wrong thing.
Actually, neither s[i]!=0 nor s[i]!='\0' are working.
-
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.
-
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.
-
Um, in my compiler, it's just going through an infinite loop.
-
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.
-
Actually, I just copy/pasted your code into my IDE and it's going through an infinite loop.
-
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.
-
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
-
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?
-
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.
-
To the integer question, yes it is. The upper limit is 2 billion or thereabouts.
-
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.
-
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.