Thread: any other way you'd write this?

1. any other way you'd write this?

Hi everyone,

I'm learning c right now and doing the exercises from the book. The exercise prompts to write
a counting program that prompts the user for three inputs:
- beginning number to start counting from
- ending number
- increment number

I wrote this:

Code:
```#include <stdio.h>

main()
{

int ifrom = 0;
int ito = 0;
int iby = 0;

scanf("%d%d%d", &ifrom, &ito, &iby);

do {

printf("\n%d\n", ifrom);
ifrom = ifrom + iby;
} while ( ifrom - iby < ito ); // end do while loop
} // end main function```
ok it seems to work but there is one thing that bothers me: in the while statement I have "ifrom - iby < ito" because (ifom < ito) counted numbers from ifrom to ito minus the increment (iby) which was wrong. Here's the question, how this can be written to work using only conditional operators without the "minus thing"

And another question is, whether you know a better way to write this little program and could you please share with me your wisdom.

Thanks for all the help guys,

2. Maybe a FOR loop?

Code:
```int i;
for(i=ifrom; i<=ito; i=i+iby)
{
}```

3. ok it seems to work but there is one thing that bothers me: in the while statement I have "ifrom - iby < ito" because (ifom < ito) counted numbers from ifrom to ito minus the increment (iby) which was wrong. Here's the question, how this can be written to work using only conditional operators without the "minus thing"
Comparing with "less-than-or-equal" may-be?

And another question is, whether you know a better way to write this little program and could you please share with me your wisdom.
A for-loop should do well too.

I'm not sure if Hungarian notation is considered good style in C. "to", "from", "by" - or "first", "last", "increment" are normal variable names, "ito", "iby" etc looks like one step towards obfuscation.

4. I think the correct behavior is to stop as soon as ifrom is greater than ito (BTW, this assumes the increment is positive - if it was negative, you would be counting downward and the criterion would be >=, not <=), which the do-while loop doesn't necessarily do since it always executes at least once. Use a for or while loop instead.

5. // wait, while writing this several other posts were made so there already could be a response to the question here

Thanks anon. 'Less than or equal too' apparently works, I tried this before and it didn't work. Now I know why :-) - I was using '=<' instead of '<='.

Now I was trying to rewrite this as a 'for' loop but I didn't know how to build the proper expression into the for (...) statement, normally if asked to do increments by 2 for example I'd use (...; x++, x++) but here since the increment is uncertain trouble begins. How would you rewrite this for loop in yet a simpler way? - I'm not very fond of the comparison in the loop.
It wouldn't work if for example istart = 7 and increment = 2
Code:
```#include <stdio.h>

main()
{
int x;
int ifirst = 0;
int ilast = 0;
int increment = 0;
scanf("&#37;d%d%d", &ifirst, &ilast, &increment);

for ( x = ifirst; x <= ilast; x++ ) {
if (x % increment != 0)
continue;
else printf("\n%d\n", x);
}
}```
Thanks again for all the help guys,

6. ok I got all the advices
and rewrote the for loop:

Code:
```#include <stdio.h>

main()
{
int x;
int ifirst = 0;
int ilast = 0;
int increment = 0;
scanf("&#37;d%d%d", &ifirst, &ilast, &increment);

for ( x = ifirst; x <= ilast; x = x + increment) {

printf("\n%d\n", x);
}
}```
and it works almost fine, but whenever somebody chooses ilast such that ilast - ifirst != 0 (mod increment) the program doesn't output anything but terminates right away. How would you fix it?

7. and it works almost fine, but whenever somebody chooses ilast such that ilast - ifirst != 0 (mod increment) the program doesn't output anything but terminates right away. How would you fix it?
Hum i don't see any reason why the condition of the for loop (x <= ilast) would be false on the first iteration in the special case that ilast - ifirst != 0 (mod increment).

Except if the user provided incorrect entry. You aren't doing any checking to see if it's the case. It's always good to check if the user provided good entry. One way to do this would looks like this

Code:
```#include <stdio.h>

#define FPURGE() while(getchar() != '\n')

int main()
{
int x;
int ifirst = 0;
int ilast = 0;
int increment = 0;
int i;

do
{
printf("Enter first, last and increment numbers: ");
i = scanf("%d %d %d", &ifirst, &ilast, &increment);
FPURGE();
} while (i != 3);

for (x = ifirst; x <= ilast; x = x + increment)
{
printf("\n%d\n", x);
}

return 0;
}```
What else can i say... am i missing something heh ?

8. I'd solve this problem in the following way:

1. Prompt the user for some numbers.
2. Check the input so that first is less than last and increment is not zero
3. Ensure that [first, last] is within the range of a long int.
4. If 2 and 3 are true, than a loop should do the work.

At least then you shouldn't have problems with integer overflow. Other than that, not that difficult really. Involving mod is a bit unnecessary I think.

9. Ok all works fine. Thanks everyone for help.
By the way, where can I look up things like FPURGE() and other functions that I need or don't know, for definition and proper usage?

10. I'd solve this problem in the following way:

1. Prompt the user for some numbers.
2. Check the input so that first is less than last and increment is not zero
3. Ensure that [first, last] is within the range of a long int.
4. If 2 and 3 are true, than a loop should do the work.
I agree totaly with point no 2, and i guess everyone will agree, except if they like having infinite loop in their programs . (that said, we should check if increment is bigger than 0)

But... i'm not sure to understand what you mean by "Ensure that [first, last] is within the range of a long int". This is necessary true since the int type can represent number only between INT_MIN and INT_MAX. The only way you could have a potentially infinite loop would be if last + increment < last (that's it, the sum of last + increment cause an integer overflow). But it's somehow a really special case for this kind of program. And after all, this program is just an example.

By the way, where can I look up things like FPURGE() and other functions that I need or don't know, for definition and proper usage?
FPURGE() is not an fonction, it's a macro i added to the code (look back at my last post). If you need more information about macro and the #define instruction, i saw there's a lot of information out there.
Personnaly, i'm using this site when i need documentation of the C library. http://www.cplusplus.com/reference/clibrary/

11. generally
x = x + increment
can be written as

x += increment

which is more commonly used idiom

12. Originally Posted by foxman
But... i'm not sure to understand what you mean by "Ensure that [first, last] is within the range of a long int". This is necessary true since the int type can represent number only between INT_MIN and INT_MAX. The only way you could have a potentially infinite loop would be if last + increment < last (that's it, the sum of last + increment cause an integer overflow).
Despite what you've said, it's reasonable to expect people to count from INT_MIN to INT_MAX or 0 to LONG_MAX. In fact there's no real problem with a smart user expecting to wrap around, but it's wrong. It is important that you read correct numbers from the user and ensure that they fit within the representable range, otherwise, a simple condition like num <= last would be perpetually true.

But it's somehow a really special case for this kind of program. And after all, this program is just an example.
It's one of the only ways the program fails to work. Even for an example, that's a pretty important oversight and really demonstrates laziness.

13. I'm still not exactly sure what you mean by
It is important that you read correct numbers from the user and ensure that they fit within the representable range, otherwise, a simple condition like num <= last would be perpetually true.
I mean, could you give me an example of a number that wouldn't fit in the representable range of an int knowing that this number is an int ? The user might enter a number too big to be representable by an int so that scanf() will store a number smaller than this one in the variable (one representable one) and the results won't be as the user expected, still, there won't be an infite loop except, like i said, last + increment < last. (in the case increment is > 0)

14. Heres another example of what can go wrong:
Code:
```#include <stdio.h>
int main()
{
unsigned char max=255; //maximum value containable
unsigned char inc=128;
unsigned char i;
for(i=0; i<max; i+=inc) printf("%i\n",i);
}```
For the sake of simplicity I replaced ints with unsigned chars. max=255 and inc=128 would both be valid input without validation.

15. I can provide an example, sure. mike_g has presented one also.

Code:
```#include <stdio.h>
#include <limits.h>

void count ( long first, long last )
{
long c;
for ( c = first; c <= last; c++ )
printf( " %d", c );
putchar( '\n' );
}

int main( void )
{
/** Each of these counting examples probably has problems with integer overflow because
* the last number that breaks the count will overflow the limits of a long integer,
* resulting in a loop that is perpetually true.
* As I've been saying, you need to make sure that [first, last] is within
* the range of a long, or whatever integral you choose.
*/
count( LONG_MIN, LONG_MAX );
count( 0, LONG_MAX );
count( INT_MIN, INT_MAX );  /** Also overflows if sizeof int == sizeof long **/

return 0;
}```