This question already has answers here:
scanf getchar function is skipped
(3 answers)
Closed 6 years ago.
I recently started to program in C and im having trouble with this code:
#include <stdio.h>
#include <stdlib.h>
#define PI 3.1416
int main () {
float x;
int y;
x = PI;
printf("Enter y: ");
scanf(" %i", &y);
printf("The new value of y is: %i.\n\n",y);
x = x * y;
printf("The new value of x is: %f.\n\n",x);
getchar();
return 0;
}
the problem appears with the getchar() at the end, the program shutdown and doesnt wait for the input. I have found a solution i dont like at all and is by adding 2 times getchar(). Is there any way around it?, im using ubuntu so system("pause") is not an option
The scanf command does not consume the Enter key that you pressed after entering y. So the getchar() happily consumes it.
One solution is to consume the rest of the input line after reading y; the code for that looks like:
int ch; while ( (ch = getchar()) != '\n' && ch != EOF ) {}
Although there are other options for pausing at the end of a program, this is probably a good idea anyway because it will be necessary if you later expand your program to expect string or character input.
A good general solution to this problem is to read input from the user using fgets, and then scan it with sscanf:
char ln[1024];
printf("Enter y: ");
fgets(ln, 1024, stdin);
sscanf(ln, "%d", &y);
You will still need to check the return values of fgets and sscanf for error conditions, but it is easier to handle line-oriented input this way.
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 6 months ago.
#include <stdio.h>
int main() {
char v1,v2,v3;
printf("enter: ");
scanf("%c",&v1);
printf("enter: ");
scanf("%c",&v2);
printf("enter: ");
scanf("%c",&v3);
}
this is my sample code and I expect an output like:
enter: a
enter: b
enter: c
but I'm getting output like:
enter: a
enter: enter:
2nd and 3rd print statements are getting executed simultaneously.
The problem is that you're reading characters, so if what you enter is actually aEnterbEntercEnter, that is actually SIX characters, and what you read will be the first 3 (the a, the Enter, and the b)
What you can do is use a space in the scanf format to skip whitespace. If you use scanf(" %c", &v1); then any whitespace (such as Enter) will be skipped, which will cause your result to be what you expect. However, if someone enters something like spaceEnter, the program will seem to hang, waiting for non-whitespace to be entered
The problem lies in buffering. Read this question, which was already mentioned in the comments.
TL,DR: Use scanf(" %c", &v); to read chars, since it ignores all whitespace from the buffer, as well as the trailing newline.
Hello what I would recommend is using a library that allows you to use a function called get_char.
I wrote a program using this function that does what you wanted yours to do.
#include <stdio.h>
#include <string.h>
#include <cs50.h>
int main(void)
{
char v1 = get_char("enter: ");
char v2 = get_char("enter: ");
char v3 = get_char("enter: ");
}
So the program stores 3 char values as they are entered one after another, without all executing at once. I don't know if this is the type of answer that you are looking for or if it will help you, but I figured I would put this out there. If its not really what your looking for let me know!
This is what the terminal looks like btw.:
$ make help
$ ./help
enter: a
enter: b
enter: c
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
C skipping one command of a function? [duplicate]
(2 answers)
Closed 6 years ago.
I've been given the pretty simple task of writing a program that will take two characters and then print the letters inbetween them using a for() loop.
Here's my code:
#include <stdio.h>
int main() {
char a, b;
printf("\nEnter the first character: ");
scanf("%c", &a);
printf("\nEnter the second character: ");
scanf("%c", &b);
for(char i = a; i <= b; i++) {
printf("%c ", i);
}
return 0;
}
When I run it, I am prompted to enter the first character correctly but when I press enter it only runs the next printf() and then terminates.
No errors or warnings or anything on compilation. Another similar question I found that was apparently solved does not work for me either.
Thanks in advance.
You have to consume the \n in stdin left by first scanf.
Fastest fix
scanf(" %c", &b);
The space before %c tells to scanf to ignore all whitespaces before to read the char.
If I read your code correctly, by pressing enter, you would enter the second character, which would most probably (depending on the environment) start with a numeric value of 13, which would be smaller than any letter, so the loop's body is executed only once.
This question already has answers here:
How to do scanf for single char in C [duplicate]
(11 answers)
Closed 6 years ago.
Just testing some code; the following is supposed to run until I enter 'n'. But it stops after one round. Can anyone explain it, and help me implement what I want?
#include <stdio.h>
int main ()
{
char another = 'y';
int num;
while ( another == 'y' )
{
printf ("Enter an number ");
scanf ("%d", &num);
printf ("square of %d is %d", num, num * num);
printf ("\nWant to enter another number y/n\n");
scanf ("%c", &another);
}
}
Thanks.
I really appreciate every one's comments. I did search online for GDB, and used it later. I have to say it made identifying the issue so much easier.
Thanks so much.
Add a space before %c
scanf (" %c", &another);
To eat the left out newline in the buffer after the previous scanf().
1) Use the standard definition of main()
int main(void) //if no command line arguments.
2) Do check the return value of scanf() (and other functions), to make sure that the values were read without any errors.
Use
scanf (" %c", &another);
^^^^^
Also it is better to write
printf ("square of %d is %lld", num, ( long long int )num * num);
^^^^ ^^^^^^^^^^^^^^^^^^^^
This question already has answers here:
Why is scanf() causing infinite loop in this code?
(16 answers)
Closed 9 years ago.
In line 5 I read an integer and isint is getting 1 if it reads an integer or 0 if it's not an integer. If isint is 0 I have a loop asking user to give an integer and I read until the user gives an integer. I try this code giving a character instead of an integer but I have an infinite loop. The program just doesn't wait to give a new input. What's wrong with my code?
#include <stdio.h>
int main(void) {
int arg1;
//int arg2;
int attacknum = 1;
int isint = 1;
//printf("Insert argument attacks and press 0 when you have done this.\n");
printf("Attack %d\n", attacknum);
attacknum++;
printf("Give attacking argument:");
isint = scanf("%d", &arg1); //line 5
while(isint == 0){
printf("You did not enter a number. Please enter an argument's number\n");
isint = scanf("%d", &arg1);
printf("is int is %d\n", isint);
}
return 0;
}
As others have mentioned, if scanf can't parse the input, it leaves it unscanned.
Generally scanf is a poor choice for interactive input because of this kind of behavior, and because it doesn't match the line-at-a-time interface experienced by the user.
You are better off reading one line into a buffer using fgets. Then parse that line using sscanf. If you don't like the input, throw the whole line away and read another one.
Something like this:
#include <stdio.h>
int main(void)
{
char line[256];
int arg1;
int isint;
while (1) {
printf("Give attacking argument:");
fgets(line, sizeof line, stdin);
isint = sscanf(line, "%d",&arg1);
if (isint) break;
printf("You did not enter a number.Please enter an argument's number\n");
}
printf("Thanks for entering %d\n", arg1);
return 0;
}
(For production code you'll want to handle long lines, check return codes, also check for trailing garbage after the number, etc.)
Actually, an even better approach would be to not use scanf if you just want to read an integer, and instead use strtol. That gives you a handy pointer to the character just after the number, and you can check that it's whitespace or nul.
When scanf is confronted with a non-digit it will not consume any input and return that zero integers were read. The non-digit will stay in the input for the next call to scanf that will behave the same as the first call, etc.
In answer to your question below. You could use fgetc to parse at least one character, but this will give the error messages for every character already typed. Typically I think you want to skip until a newline. To this end you could use fgets as suggested by poolie. Or you could add the following after scanf.
int ch;
if (isint == 0)
while ((ch = fgetc(stdin)) != EOF && ch != '\n')
{
/* Skip characters */
}
P.S: In your case it is probably better to put it just before the first printf in the loop.
My program which finds prime factors is all set...the only thing left that I need to do is this type of output:
Do you want to try another number? Say Y(es) or N(o): y
//asks for another number (goes through the program again)
Do you want to try another number? Say Y(es) or N(o): n
//Thank you for using my program. Good Bye!
I have my attempt at this below...When I type n it does the correct output. But if I type 'y' it just says the same thing n does....How can I loop the entire program without putting the code for the program inside this while loop I have? So when I press y it goes through the program again?
int main() {
unsigned num;
char response;
do{
printf("Please enter a positive integer greater than 1 and less than 2000: ");
scanf("%d", &num);
if (num > 1 && num < 2000){
printf("The distinctive prime facters are given below: \n");
printDistinctPrimeFactors(num);
printf("All of the prime factors are given below: \n");
printPrimeFactors(num);
}
else{
printf("Sorry that number does not fall within the given range. \n");
}
printf("Do you want to try another number? Say Y(es) or N(o): \n");
response = getchar();
getchar();
}
while(response == 'Y' || response == 'y');
printf("Thank you for using my program. Goodbye!");
return 0;
} /* main() */
The problem is probably, that you're getting something that isn't y from getchar and the loop exits, as the condition is not matched.
getchar() may use a buffer, so when you type 'y' and hit enter, you will get char 121 (y) and 10 (enter).
Try the following progam and see what output you get:
#include <stdio.h>
int main(void) {
char c = 0;
while((c=getchar())) {
printf("%d\n", c);
}
return 0;
}
You will see something like this:
$ ./getchar
f<hit enter>
102
10
What you can see is that the keyboard input is buffered and with the next run of getchar() you get the buffered newline.
EDIT: My description is only partially correct in terms of your problem. You use scanf to read the number you're testing against. So you do: number, enter, y, enter.
scanf reads the number, leaves the newline from your enter in the buffer, the response = getchar(); reads the newline and stores the newline in response, the next call to getchar() (to strip the newline I described above) gets the 'y' and your loop exits.
You can fix this by having scanf read the newline, so it doesn't linger in the buffer: scanf("%d\n", &number);.
When reading input using scanf (when you enter your number above), the input is read after the return key is pressed but the newline generated by the return key is not consumed by scanf.
That means your first call to getchar() will return the newline (still sitting in the buffer), which is not a 'Y'.
If you reverse your two calls to getchar() - where the second one is the one you assign to your variable, your program will work.
printf("Do you want to try another number? Say Y(es) or N(o): \n");
getchar(); // the newline not consumed by the scanf way above
response = getchar();
just put getchar() after scanf statement of yours that will eat the unnecessary '\n' from buffer...
As others have stated, there is a single '\n' character in the input stream left over from your earlier call to scanf().
Fortunately, the standard library function fpurge(FILE *stream) erases any input or output buffered in the given stream. When placed anywhere between your calls to scanf() and getchar(), the following will rid stdin of anything left in the buffer:
fpurge(stdin);