C code help(can't find the reason that causes problem)
Greetings , to cut it short , below is the code
The Code
// This program would sum up all the integer provided by user
#include <stdio.h>
int main(void)
{
int sum = 0; // initialize and declare variable
int num;
char check;
int status;
printf("Please enter an integer to be summed :"); // prompt user for an integer
status = scanf("%d" , &num);
while(status == 1) //If user enter an integer , while loop test condition is true
{
sum = sum + num; //sum 开发者_StackOverflow中文版the input integer
printf("Do you wanna add more integer?(y/n) :"); //Asking for user next action
scanf("%c" , &check);
if(check == 'y') //Check user's answer
status = scanf("%d" , &num);
else
status = 0;
}
return 0;
}
The problem
The first thing I do when I run the program is to provide an integer , after that it would just print out the control-string Do you wanna add more integer?(y/n) :
.Then the problem arouse , instead of waiting for me to type y
or n
, the program would just end itself , which mean in Windows command prompt it would give me the line Press any key to continue....
.
I keep read through the code line by line to find any semantic error (assume there's no syntax error since compiler would've complained if there's one) or any logical error that I made , but to no avail.So I suspect is it there's any rules of C that mention We shouldn't prompt use if()
with character as test value when it is enclosed in while()
loop or any other thing that I've neglected??
Thanks for keeping yourself tied up to read my problem , hope I would really learn from you guys, do point out any mistake I made as I'm a learner who ready to accept any comment or teaching that is correct.
You're using scanf()
. My general rule is: don't.
The problem is that scanf()
of pretty much anything will leave the characters after the value you read (usually a newline) in the buffer, except that %c
reads the next character regardless of what it is. So you get the newline there, and then the y/n response is passed to the next scanf()
.
I prefer to read lines and then sscanf()
out of them; that way I know exactly what I'm getting.
Put getchar() after each scanf to clear the stdin input buffer from the trailing line feed character '\n' that gets added to the buffer when the user presses enter.
You are entering a number and then pressing enter key. The "%d"
format string will read upto the the first integer and not read the newline character that you enter. That newline character would stay inside the buffer, which gets read on the first scanf
in the loop with the "%c"
specifier. Therefore the check == 'y'
becomes false as check
contains 0x0a
, ie the newline ASCII equivalent, after it has read the new line.
Note that, if you want to make exactly your code snippet work then you need to enter the numbers and the y/n options one after another without any newline (0x0a
) or blank space (0x20
) or other separators. For example if you like to sumup the list 1,2,3,4,5 then you need to enter it as follows in your code: 1y2y3y4y5n
. If you enter a printf
statement printing the status
value after the scanf
asking for the yes/no, you can clearly see that the last unread character is being read by the "%c"
.
If you want to input the numbers and option separated What you need is to consume the extra character. Which you can do by using a getchar ()
or using the argument suppression operator in the format string: scanf ("%*c%c", &check)
. This "%*c"
will read one character from the stdin
and then simply discard it, and then the "%c"
will get your input into the check
variable. But if you enter an extra new line or have , say, some trailing spaces before the options you enter, or after the number you have entered, then it will make only one of these be consumed by the above and discarded, and the same problem will arise.
You can also use the string scanf (" %c", &check);
the " %c"
(note the trailing blankspace) will skip any number of blankspace character you enter before entering the first character.
It actually depends how you want to interpret and handle the input, you need to adjust as per it. Probably make :
char check[2];
while (status == 1)
{
sum += num;
printf("Do you wanna add more integer?(y/n) :"); //Asking for user next action
scanf("%s" , check);
if ((check[0] == 'y')&&(check[1] == '\0')) //Check user's answer
status = scanf("%d" , &num);
else
status = 0;
}
or simply use strcmp (check, "y") == 0
or other ways.
Here is the edited code working for me:
#include <stdio.h>
#include <conio.h>
int main(void)
{
int sum = 0;
int num;
char check;
int status=1;
printf("Please enter an integer to be summed :");
status = scanf("%d" , &num);
while(status == 1)
{
sum = sum + num;
printf("Do you wanna add more integer?(y/n) :");
fflush(stdin);
check = getche();
if(check == 'y')
status = scanf("%d" , &num);
else
status = 0;
}
printf("\nThe sum is: %d",sum);
getch();
return 0;
}
status starts off as undefined. You want to make sure that the input/sum loop runs at least once, therefore you should set it to 1 initially. That way you know it will always run the first time.
What @geekosaur has said about scanf() is true - it will leave things in the input buffer which will cause strange behaviour for following input statements. But it's fine to use scanf(), as long you clear stdin every time you use it. If you are using Windows there is a ready-made function:
fflush(stdin);
If you are using another operating system (or you want your code to be portable) you can search for a similar function to include in your program. Input in C is just one of the awful things that the beginner programmer needs to work around (you get used to it). I believe it may help as well if you put spaces at the beginning of the scanf() format string each time you are using it - eg.
scanf(" %d");
This should tell the program to ignore any whitespace already in the input (including newlines).
One thing to note is that you really have 2 status inputs here - the int status and the char check. You could make things a bit simpler for yourself by setting the condition as the user input:
char check = 'y';
...
while(check == 'y')
This should create the same behaviour as what you have now. I used a do-while loop instead:
// This program would sum up all the integer provided by user
#include <stdio.h>
int main(void)
{
int sum = 0;
int num;
char check;
do // a do-while loop always runs at least once - perfect for input validation
{
printf("Please enter an integer to be summed :");
fflush(stdin); //only in Windows - remove for other OS
scanf(" %d" , &num);
sum += num; //another way of writing sum = sum + num
printf("Do you wanna add more integer?(y/n) :");
fflush(stdin); //only in Windows - remove for other OS
scanf(" %c" , &check);
}while(check == 'y');
//if you want to print the sum...
printf("The sum is %i\n", sum);
getchar();
return 0;
}
It did work for me on Windows with the fflush() calls removed.
精彩评论