C cannot read string after I read an integer [duplicate] - c

This question already has answers here:
C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf [duplicate]
(7 answers)
Closed 7 years ago.
Below is my source code. After I read the integer, the program should wait until I type a string and then press enter. However, as soon as I enter the integer, the program exits. Can you tell me where is my fault?
#include <stdio.h>
#include <string.h>
int main()
{
int n;
char command[255];
scanf("%d", &n);
fgets(command, 255, stdin);
return 0;
}
I mention that I also tried to use gets(command), but I get the same result.

There is a trailing newline, since you press ENTER after the integer. Eat it by changing this:
scanf("%d", &n);
to this:
scanf("%d ", &n); // this will eat trailing newline
As chux said, scanf("%d ", &n) will not return until the user enters the number and some following non-white-space.
Relevant question: C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf
Also I have in mind my example: Caution when reading char with scanf .
Also, as Marco stated, you could use: scanf("%d\n", &n);, which targets the newline specifically.
There is also this possibility:
#include <stdio.h>
#include <string.h>
int main()
{
int n;
char command[255], newline;
scanf("%d", &n);
scanf("%c", &newline); // eat trailing newline
fgets(command, 255, stdin);
return 0;
}
However, I would personally use two fgets() and no scanf(). :)

The scanf() leaves newline character after the integer, and fgets() will read it and exit.
Try reading all input with fgets().
#include <stdio.h>
#include <string.h>
int main()
{
char buffer[255];
int n;
char command[255];
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &n);
fgets(command, sizeof(command), stdin);
return 0;
}

Typing "3c" and pressing enter in your console will make your input buffer stdin look like this: {'3','c','\n'} and would work, since scanf consumes the 3, fgets consumes the c, and the \n would be where fgets stops.
But if you type "3" and press enter, scanf will consume the 3, and the newline character will be left, causing fgets to consume no characters.

Related

Why is fgets waiting for input before it's even called?

I'm trying to write a simple program to read an integer and then a string, then print both to standard output. Ideally, the execution should look something like this:
Input the number.
> 10
Input the string.
> a string
number: 10
string: a string
However, when I run the program, it freezes after the call to scanf() until more input is provided.
Input the number.
> 10
a string
Input the string.
>
number: 10
string: a string
Why is it waiting for input before fgets() is ever called?
#include <stdio.h>
int main()
{
int number;
char string[32];
printf("Input the number.\n> ");
scanf("%d\n", &number);
printf("\nInput the string.\n> ");
fgets(string, 32, stdin);
printf("\nnumber: %d\nstring: %s\n", number, string);
}
From a previous post...
https://stackoverflow.com/a/5918223/2203541
#include <stdio.h>
int main()
{
int number;
int c;
char string[32];
printf("Input the number.\n> ");
scanf("%d", &number);
do
{
c = getchar();
} while (c != '\n');
printf("\nInput the string.\n> ");
fgets(string, 32, stdin);
printf("\nnumber: %d\nstring: %s\n", number, string);
}
"Why is fgets waiting for input before it's even called"
fgets() does not act until it is called, but if when called, and if pointing to stdin and there is content remaining in the stdin stream, it will consume it immediately. If that contents contained EOF, n-1, OR a newline (read link) execution flow will continue.
The problem here is that scanf() (called prior to fgets()) is notorious for doing exactly what it is asked to do. For example, upon user entering 12<return> two recognizable items are entered into stdin, digits and a newline but by using "%d" as the format specifier, only the first of those items is consumed, leaving the \n hanging, until the very next call to fgets(), which accepts it as input, allowing execution flow to resume immediately (as described above), causing the apparent skip you are seeing.
[This is one (of several) examples that will provide a work around for the scanf() issue:
Change this:
printf("Input the number.\n> ");
scanf("%d", &number);//leaves the newline
To this:
char c;
...
printf("Input the number.\n> ");
scanf("%d%c", &number, &c);//consumes the newline
From comments:
"is there a way to use fgets to read an integer"
Yes, I prefer fgets() coupled with your favorite string to number converter. (There are several) The simplest is this:
char cNum[10];
int num;
printf("Input the number.\n> ");
if(fgets(cNum, sizeof cNum, stdin))
{
num = atoi(cNum);
}
else //handle error
See also strtol() for a more robust solution.
Alright, so I played around with it some more and did a little more studying on scanf() format syntax, and figured out a solution. Apparently, putting the whitespace character at the end of my scanf call there tells it to keep reading until it finds something AFTER the whitespace, so of course it would hang up there until you give more input.
Remove the whitespace character in the scanf formatter, and add a leading space to the following scanf call.
The reason I had used fgets originally was so I could specify a buffer length to avoid overflow. Apparently, the same effect can be achieved using %32s in the scanf call. The fixed code looks like this:
#include <stdio.h>
int main()
{
int number;
char string[32];
printf("Input the number.\n> ");
scanf("%d", &number);
printf("\nInput the string.\n> ");
scanf(" %32s", &string);
printf("\nnumber: %d\nstring: %s\n", number, string);
}

Read user input twice in a for-loop using fgets and scanf [duplicate]

This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 1 year ago.
CODE:
#include<stdio.h>
#include<stdlib.h>
int main(){
struct mobile{
char N[10];
int ram, pixel, price;
}B[5];
int min;
char trash;
for(int i = 0; i < 5; i++){
printf("Enter Mobile Name: ");
fgets(B[i].N, sizeof(B[i].N), stdin);
printf("Enter features (ram/camera pixels/price): ");
scanf("%d%d%d", &B[i].ram, &B[i].pixel, &B[i].price);
printf("\n");
}
}
The program is not accepting value for name of mobile second time. It prints Enter mobile name but don't take value then print Enter features and ask for value. I tried adding a second scanf above printf("\n"); but didn't work. Help please. Thanks.
Remove \n from buffer
scanf leaves a newline in the buffer, which is then read by fgets. The other problem is, that you aren't dividing the user input using a delimiter so I would put a space or a slash between the type specifiers %d:
scanf("%d/%d/%d\n", &B[i].ram, &B[i].pixel, &B[i].price);
The input should then be something like this:
Enter specs (ram/pixels/price): 8/12/500
The trailing character \n is now being read, but it isn't stored in any variable.
Remove \n from fgets() input
This doesn't cause your problem, but I would also remove the trailing \n from the fgets() input, because it's probably not supposed to be part of the phone's name.
#include <string.h>
fgets(B[i].N, sizeof(B[i].N), stdin);
B[i].N[strcspn(B[i].N, "\n")] = '\0';

Why gets does not work when I use it with scanf?

When i use gets separately this works. But, when i use scanf in my program it does not work. Can anyone explain what I've missed?
#include <stdio.h>
#include <stdlib.h>
int main(){
char a[]="computer";
char b[]={'p','c','\0'};
char c[30];
char d[30];
printf("a=%s,b=%s\n",a,b);
printf("enter a word\n");
scanf("%s",c);
printf("%s",c);
printf("enter a sentence\n");
gets (d);
printf("%s",d);
return 0;
}
gets doesn't skip the white-space characters before starting to read the string while scanf does.
After your first input, there is \n character in the buffer left behind by first scanf call. This \n is read by gets but scanf skips this white-space character.
this can be solved by using a getchar statement after the scanf call.
printf("enter a word\n");
scanf("%s",c);
getchar();
Do not use gets neither scanf (they do not check array bound), instead use fgets.
printf("enter a word\n");
fgets(c, 30, stdin);
printf("%s",c);
printf("enter a sentence\n");
fgets(d, 30, stdin);
printf("%s",d);
Scanf leaves behind "\n"(without quotes) and then gets() function reads only it.
scanf("%s",c) left the Enter or \n in stdin. When gets() executed it consumed that and returned an empty string. gets() reads in all data up to the \n and trims it off before returning.
The format specifiers like %d %s, etc. (all except %n %c %[) and the whitespace format directives like " " direct scanf() to skip leading whitespace. scanf() itself does not skip leading whitespace.
Suggest using fgets() and avoid using gets().
char buf[100];
printf("enter a word\n");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%29s", c); // 29 because c is size 30
printf("%s\n",c);
printf("enter a sentence\n");
fgets(d, sizeof d, stdin);
printf("%s",d);
scanf removes whitespace automatically from before the datum it's trying to get. An exception to this is the character formats (primarily %c), which don't remove whitespace. However, scanf leaves whitespace after the datum. Therefore, you'll need a way to get rid of that. Use
getc(stdin);
you can then continue on your merry way. This page has more documentation on getc.

Why is the first string ignored when reading with fgets from stdin? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dev-C++ Input skipped
I am trying to read an array of character strings from stdin using fgets, but the first string I want to read is always ignored. What is causing this issue?
#include <stdio.h>
int main()
{
int i;
struct material
{
char name[30];
float price, kg;
};
unsigned m,nr;
printf("Lorry capacity=");
scanf("%u", &m);
printf("Number of materials=");
putchar('\n');
scanf("%u", &nr);
struct material list[nr];
for (i=0; i<nr; i++)
{
printf("Name=");
fgets(list[i].name, 30, stdin);
}
putchar('\n');
for (i=0; i<nr; i++)
{
printf("%s ", list[i].name);
}
return 0;
}
scanf("%u", &nr);
struct material list[nr];
for (i=0; i<nr; i++)
{
printf("Name=");
fgets(list[i].name, 30, stdin);
The scanf("%u", &nr); leaves the newline in the input buffer, so fgets finds an empty line without requiring further input to be entered.
It is generally a bad idea to mix (f)scanf and fgets, for that reason (among others).
As a quick fix, empty the input buffer before the first fgets,
int ch;
while((ch = getchar()) != EOF && ch != '\n');
if (ch == EOF) {
// oops
}
A more principled fix would be to read in the values before using fgets to get an entire line including the newline, and decode the numbers with strtoul or maybe sscanf.
This is a very common error. After reading a number with scanf, the newline you typed by pressing ENTER is left in the input buffer, so the first call to fgets reads the (very short) line that consists of only that newline.
I noticed that I can get rid of the newline left in the input buffer, by reading it with getchar().
Also, I had to use the following code to remove the trailing newline character from fgets() input:
char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
*pos = '\0';
One of the things that's generally misunderstood is that when you ask for input from the user, you get freebies.
When the computer ask for the amount of materials:
Number of materials=
51
And you enter "51" you're really getting three characters: '5', '1', and '\n'. Everything comes with a newline character when you hit the enter key.
Different utilities that get input from the user handle this different. fgets() will read the newline and then it stores the input as "51\n". If you read it as a string using scanf()'s string format specificer "%s" you'll get only the digits "51" and the newline character is left on the stdin buffer.
So in your case you read a number via scanf:
scanf("%u", &nr);
Which leaves the newline, then when you try to do the next read:
fgets(list[i].name, 30, stdin);
fgets picks up that newline and stores it.
So there's a bunch of fixes possible here, one is to just use fgets() only, another is to consume the newlines with getchar() after each scanf, choice is up to you.
BTW: You can insert a newline in your printfs: printf("Number of materials=\n");
You can just do a fgets after each scanf, which will then eat the pending newline:
char dummy[10];
...
scanf (...);
fgets (dummy, 1, stdin);

scanf gets the input of the previously excecuted getchar()

I am using getchar() in order to read characters and put them on a table, as well as scanf in order to get an integer.
The problem with the scanf() is that it doesn't wait for the users' input but reads from the buffer the last character given on the previous line, with getchar().
I tried sscanf, fflush(stdin); etc but I'm getting still the same behavior.
#include <stdio.h>
#include <stdlib.h>
main()
{
int i, choice, tmp_day, tmp_month;
char name[5];
printf("insert choice(1-3):\n");
scanf("%d",&choice);
printf("name: ");
for (i=0;i<5;i++) name[i]=getchar();
name[5] = '\0' ;
printf("day (1-31): ");
scanf("%d",&tmp_day);
printf("month (1-12): ");
scanf("%d",&tmp_month);
printf("\n%d %d", tmp_day, tmp_month);
}
Any idea?
Thanks in advance.
Detailed discussion about fflush(stdin) which not necessarily portable.
http://c-faq.com/stdio/gets_flush2.html
After each scanf use this statement:
fflush(stdin);

Resources