Use 'scanf()' scanning in decimal problem

1
2
3
4
5
6
7
8
9
int main() {
  int num ;
  while ( num != -1 ) {
    scanf( "%d", & num ) ;
    printf( "%d\n", num ) ;
  } // while
  
  return 0 ;
} // main() 


I found if type in decimal (ex:123.456), it always just can scan in first number (print '123' always), and loops forever.

Why (or how) it happens ?

p.s. MSVC 6.0 SP6
Last edited on
The first time through the loop, scanf() scans characters until it sees an invalid character
for an integer (in this case the decimal point). scanf() leaves the decimal point in the
"scan buffer". Then you print the number and repeat. The second time scanf() is
called, it still sees the decimal point, returns without altering num, and then you print
it again. Rinse and repeat, ad infinitum.

So.. it's a missing case @@?
Did I find the bug ? XD
Last edited on
Hint: scanf() returns a value.
The format specifier %d means decimal integer, which I think you are confusing with the normal meaning of decimal which means a number with a decimal point.

Try this:

1
2
3
4
5
6
7
8
9
int main() {
  int num ;
  while ( num != -1 ) {
    scanf( "%f", & num ) ;
    printf( "%f\n", num ) ;
  } // while
  
  return 0 ;
} // main()  


Here I used %f which is a floating point number. This is what C uses to mean a number with a decimal point (actually its a binary point but that's not important to this).

So:
%d = decimal integer (2435)
%f = floating point (20.756)
To: PanGalactic
Wow, this is why EOF is -1.
Then find out a 0 case.
Thanks. :)


To: Galik
Well.. I think I need to talk why I found out this case reason..
Original, I must input a file with integer.
Then I think some special case. (unnecessary)
( Of course there are many method to do. ( fscanf, FILE, string to integer, float to integer...etc. ) )
( I think %d is a easy way for me to do this program. )
I think "If input is a float, what it will happen ?"
'fscanf' is similar to 'scan', so I try it.

Then, found it's not spliting token by point. ^^"

So.. I can use %f then assign to int, but ignore after point number.
Or I use %s then strtok(). etc.

Thank you. :)
Last edited on
Another question:
How to scan in integer, and separate by point without use '%s then strtok()' this method ?
It seem must to use string to handle...(?)
The return value from scanf() will tell you how many values were successfully read. So you can determine if the input was legal or not by testing it with if().

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstdio>

int main()
{
	int num = 0; // set to zero to make sure it doesn't equal -1
	while(num != -1)
	{
		if(scanf("%d", &num) != 1) // expecting to read ONE integer number
		{
			break; // illegal input (like a '.')
		}
		printf("%d\n", num);
	}

	return 0;
}
Last edited on
yes...
But it can't get the integer after the point.
Ex: 123.456
'%d' can get 123, but it can't get 456.
If I must get 456 integer, it seem only use string to handle.
Last edited on
Thanks for God.
I found the solution:
1
2
3
4
5
6
7
8
9
10
11
int num ;
char ch ;
int scanNum = scanf( "%d", & num ) ;
while ( num != -1 ) {
  if ( scanNum == 0 ) {
    scanf( "%c", & ch ) ;  // scan the point
    scanNum = scanf( "%d", & num ) ;
  } // end if ( scanNum == 0 )
  printf( "%d\n", num ) ;
  scanNum = scanf( "%d", & num ) ;
} // while ( scanNum != EOF ) 
Last edited on
Does this have to be in C?
To moorecm:
Other solution @@?
I am still not exactly sure what you want this to do, but if you need to get the number before the '.' and the number after the '.' as two separate integers then you could do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <cstdio>

int main()
{
	int num1, num2;

	if(scanf("%d.%d", &num1, &num2))
	{
		printf("1st: %d\n", num1);
		printf("2nd: %d\n", num2);
	}

	return 0;
}
Last edited on
Topic archived. No new replies allowed.