scanf is skipped (?) - c

I tried to do a small Worker Register, but it skips completely the second scanf, which gets address value. I am a beginner, so I do not know what I am doing wrong. Here is the code:
#include <stdio.h>
int main()
{
// var
char n[256], ad[256]; // n - Name, ad - Address
int i, ag; // i - Income, ag - Age
// code
printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
scanf("%255[^\n]", n);
printf("Address: ");
scanf("%255[^\n]", ad);
printf("Age: ");
scanf("%d", &ag);
printf("Income: R$");
scanf("%d", &i);
printf("Worker %s\nAddress: %s\nAge: %d\nIncome: R$%d", n, ad, ag, i);
return 0;
}
I really appreciate any help you can provide!

Nad's hack of adding a getchar() seems to fix it, but I wouldn't use scanf for reading strings if I were you.
It's nicer to use fgets() reading strings instead. scanf on a string is problematic. See: Reading a string with scanf
e.g.
#include <stdlib.h>
...
printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
fgets(n, 256, stdin);
...
Regarding the size parameter in fgets(). The man page states:
fgets() reads in at most one less than size characters from stream
and
stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer.
A terminating null byte ('\0') is stored after the last character in
the buffer.
Therefore you enter the size of the buffer and ignore the null byte as fgets will do that work for you.

Just simply add a getchar(); To be honest, I don't know why but this has happened to me plenty of times in school. It seemed to fix it :)
code:
#include <stdio.h>
int main()
{
// var
char n[256], ad[256]; // n - Name, ad - Address
int i, ag; // i - Income, ag - Age
// code
printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
scanf("%255[^\n]", n);
printf("Address: ");
getchar();
scanf("%255[^\n]", ad);
printf("Age: ");
scanf("%d", &ag);
printf("Income: R$");
scanf("%d", &i);
printf("Worker %s\nAddress: %s\nAge: %d\nIncome: R$%d", n, ad, ag, i);
return 0;
}

"%255[^\n]" meant input up to newline(accepts inputs other than newline).(The newline isn't included.)
So, there is a newline in the input buffer(of stdin),
second scanf (scanf("%255[^\n]", ad); ) also accepts inputs other than newline,
So, It will not be entered.
Therefore you need to consume the newline in first scanf.
E.g scanf("%255[^\n]%*c", n); %*c ignores one character(That is the newline).
Since %d of 3rd scanf skips the previous white-spaces, %*c isn't necessary for 2nd scanf.

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);
}

C program not printing the string that is given as input

I want the output to print the data that we print. but it is not working as expected and the output is not displaying and it is exiting
#include <stdio.h>
int main() {
char name[20], department[3], section[1];
printf("enter the name of the student:");
scanf("%s", name);
printf("enter your department:");
scanf("%s", department);
printf("enter the section");
scanf("%s", section);
printf("Name:%s \n Department:%s \n Section: %s ", name, department, section);
return 0;
}
Your program has undefined behavior because the arrays are too short and scanf() stores the user input beyond the end of the arrays, especially the last one, section that can only contain an empty string which scanf() cannot read anyway.
Make the arrays larger and tell scanf() the maximum number of characters to store before the null terminator, ie: the size of the array minus 1.
Here is a modified version:
#include <stdio.h>
int main() {
char name[50], department[50], section[50];
printf("enter the name of the student:");
if (scanf("%49s", name) != 1)
return 1;
printf("enter your department:");
if (scanf("%49s", department) != 1)
return 1;
printf("enter the section");
if (scanf("%49s", section) != 1)
return 1;
printf("Name:%s\n Department:%s\n Section: %s\n", name, department, section);
return 0;
}
Note that using scanf with a %s conversion requires that each data item be a single word without embedded spaces. If you want name, department and section to accommodate spaces, which is more realistic for anyone besides Superman Krypton A, you would use %[\n] with an initial space to skip pending whitespace and newlines (or fgets() but in another chapter):
#include <stdio.h>
int main() {
char name[50], department[50], section[50];
printf("enter the name of the student:");
if (scanf(" %49[^\n]", name) != 1)
return 1;
printf("enter your department:");
if (scanf(" %49[^\n]", department) != 1)
return 1;
printf("enter the section");
if (scanf(" %49[^\n]", section) != 1)
return 1;
printf("Name:%s\n Department:%s\n Section: %s\n", name, department, section);
return 0;
}
scanf(" %49[^\n]", name) means skip any initial whitespace, including pending newlines from previous input, read and store and bytes read different from newline, up to a maximum of 49 bytes, append a null byte and return 1 for success, 0 for conversion failure or EOF is end of file is reached without storing any byte. For this particular call, conversion failure can happen if there is an encoding error in the currently selected locale.
The problem is that you have not accounted for the null character. It should work with the following.
char name[20] , department[4] , section[2];
The reason this happens is that C requires an extra character for the null character \0 which tells the program when the string ends.
first of all you should respect the size of string ,so you should either convert section to char or increase the size of that string because you have here the problem of '\0' character...so the rule is : the size of string is the size what you need + 1 for '\0' NULL character
and her is two program i tried to Modification you program for two scenarios :
#include <stdio.h>
int main(){
/// any size you like just respect the NULL character
char name[20],department[4],section[23];
printf("enter the name of the student:");
scanf("%s",name);
printf("enter your department:");
scanf("%s",department);
printf("enter the section");
scanf ("%s",section);
printf("Name:%s \n Department:%s \n Section:%s ", name,department,section);
return 0;
}
and case of char :
#include <stdio.h>
int main(){
char name[20],department[4];
char section;
printf("enter the name of the student:");
scanf("%s",name);
printf("enter your department:");
scanf("%s",department);
printf("enter the section");
///don't forget this space before %c it is important
scanf (" %c",&section);
printf("Name:%s \n Department:%s \n Section:%c ", name,department,section);
return 0;
}
I watched for a long time and finally found the problem.
This is problem: char section[1];.
You declared the size is too short.
It looks like this after you declared it: section[0] = '\0';.
If you scanf a, the array data like section[0] = 'a';, and then it automatically add '\0' somewhere, so you got a memory leaking.
So replace char section[1]; to char section[2];.
I will not insist in the reasons of the other answers (that state other problems in your code than the one you are asking for) but I'll limit my answer to the reasons you don't get any output before the first prompt (there's no undefined behaviour before the third call of printf if you have input short enough strings to not overflow the arrays --- the last is impossible as long as you input one char, because to input one char you heed at least space for two)
I want the output to print the data that we print. but it is not working as expected and the output is not displaying and it is exiting
stdio works in linebuffer mode when output is directed to a terminal, which means that output is written to the terminal in the following cases:
The buffer is filled completely. This is not going to happen with a sort set of strings.
There is a \n in the output string (which there isn't, as you want the cursor to remain in the same line for input as the prompt string)
As there is no \n in your prompts, you need to make printf flush the buffer at each call (just before calling the input routines) You have two ways of doing this.
Calling explicitly the function fflush(3), as in the example below:
printf("enter the name of the student:");
fflush(stdout); /* <-- this forces flushing the buffer */
if (scanf(" %49[^\n]", name) != 1)
return 1;
configuring stdout so it doesn't use buffers at all, so every call to printf forces a write to the standard output.
setbuf(stdout, NULL); /* this disables buffering completely on stdout */
/* ... later, when you need to print something */
printf("enter the name of the student:"); /* data will be printed */
if (scanf(" %49[^\n]", name) != 1)
return 1;
But use this facilities only when it is necessary, as the throughput of the program is degraded if you disable the normal buffering of stdio.

scanf() function doesn't work? [duplicate]

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 8 years ago.
This may be a simple question, but i searched a lot and still didn't figure it out.
I compiles below snip code by gcc and run program from terminal. In correct, It allow to enter an int and a char but it doesn't. It doesn't wait to enter the char??
Anyone here can help me will be kind. thanks in advance!
#include <stdio.h>
int main()
{
char c;
int i;
// a
printf("i: ");
fflush(stdin); scanf("%d", &i);
// b
printf("c: ");
fflush(stdin); scanf("%c", &c);
return 0;
}
%d will read consecutive digits until it encounters a non-digit. %c reads one character. Probably what's happening is that you're giving it a number (several digits) followed by a new line. %c then reads in that new line. You were probably intending for the fflush(stdin); to discard anything that hadn't yet been read, but unfortunately, that's undefined behavior.
The solution is to discard all whitespace before reading the character:
scanf(" %c", &c);
Note the space at the start. That means to discard all whitespace.
You can use the getchar() to achieve what you want.
or consume the extra newline by using:-
scanf(" %c", &c);
^^^ <------------Note the space
Reason:- Your next scanf for reading the character just reads/consumes the newline and hence never waits for user input
Instead of fflush(stdin); scanf("%c", &c);
1.use scanf with extra space
scanf(" %c",&c);
or
2.use getchar() two times , first time reads '\n' which is entered after giving integer input and second time call ask you for give input as c:
getchar();
c=getchar();
would help you.
First of all, scanf works when used as directed. I think the following code does what you want. Stdout is flushed so that user is prompted to enter an integer or a character. Using %1s allows white space like \n.
int main()
{
char c[2];
int i;
printf("i: ");
fflush(stdout);
scanf("%d", &i);
printf("c: ");
fflush(stdout);
scanf("%1s", &c);
printf("\ni = %d, c = %c", i, c[0]);
return 0;
}
This code was tested/run on an Eclipse/Microsoft C compiler.
That fflush() is not guaranteed to do anything, and gcc/g++ doesn't. Not on Linux, anyway.
I thought I invented the following way to flush the rest of a line...until I saw it as an example in the ISO C spec (90 or 99...forgot which, but it's been there a long time either way...and I'll bet most readers here have seen it before.)
scanf("%*[^\n]%*c"); /* discard everything up to and including the next newline */
You can put that in your own "flush" function to save typing or pasting that all over the place.
You should still follow the suggestions to to put a space in scanf(" %c", &c);.
That will patiently wait for a non-whitespace character in case of a leading space or a double hit of the enter key.

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);

Functions and arrays

My little program below shall take 5 numbers from the user, store them into an array of integers and use a function to print them out. Sincerly it doesn't work and nothing is printed out. I can't find a mistake, so i would be glad about any advice. Thanks.
#include <stdio.h>
void printarray(int intarray[], int n)
{
int i;
for(i = 0; i < n; i ++)
{
printf("%d", intarray[i]);
}
}
int main ()
{
const int n = 5;
int temp = 0;
int i;
int intarray [n];
char check;
printf("Please type in your numbers!\n");
for(i = 0; i < n; i ++)
{
printf("");
scanf("%d", &temp);
intarray[i] = temp;
}
printf("Do you want to print them out? (yes/no): ");
scanf("%c", &check);
if (check == 'y')
printarray(intarray, n);
getchar();
getchar();
getchar();
getchar();
return 0;
}
Change your output in printarray() to read:
printf("%d\n", intarray[i]);
^^
That will add a newline after each number.
Normally, output written to the console in C is buffered until a complete line is output. Your printarray() function does not write any newlines, so the output is buffered until you do print one. However, you wait for input from the user before printing a newline.
Change to that:
char check[2];
And also that:
scanf("%s", check);
if (!strcmp(check,"y"))
printarray(intarray, n);
Hope that helped. Your scanf("%c", &check); failed. Instead of y you end up having NL (ASCII code 10), which means the if part fails.
I don't know if it a nice fix though. Maybe someone could give a better one. Keep in mind if you input something bigger (eg yess) you going to get a bit unlucky ;)
Aside from the suggestions about printing the \n character after your array (which are correct), you also have to be careful with your scanf that expects the "yes/no" answer. Muggen was the first one to notice this (see his answer).
You used a %c specified in your scanf. %c specifier in scanf does not skip whitespace, which means that this scanf will read whatever whitespace was left in the input buffer after you entered your array. You hit the "Enter" key after entering the array, which put a newline character into the input buffer. After that scanf("%c", &check) will immediately read that pending newline character instead of waiting for you to enter "yes" or "no". That's another reason your code does not print anything.
In order to fix your scanf, you have to force it to skip all whitespace characters before reading the actual answer. You can do that by scanf(" %c", &check). Note the extra space before %c. Space character in scanf format string forces it to skip all continuous whitespace beginning from the current reading position. Newline character happens to be whitespace, so it will be ignored by this scanf.
printf("%d", intarray[i]);
add new line after this

Resources