Line of code skipped when getting user input in C [duplicate] - c

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 2 years ago.
In my program I have the user input a phrase, and I use the fgets function to retrieve it so it can count the spaces between words. The problem is my program skips over fgets and continues into the next scanf. Can someone explain what's the problem and how I can fix it?
#include<stdio.h>
#include<string.h>
int main(){
char plaintext[50], key[15];
char encrypt[50];
int EncryptOp = 1, DecryptOp = 2, choice;
printf("Enter 1 for Encryption or 2 For Decryption: ");
scanf("%d", &choice);
if(choice ==EncryptOp){
printf("Enter Plaintext for Encryption: ");
fgets(plaintext,50,stdin);
printf("Enter Keyword:");
scanf("%s", &key);
printf("Plaintext:%s\n Keyword:%s\n", plaintext, key);
}else if(choice ==DecryptOp){
printf("Enter Encrypted Message for Decryption: ");
scanf("%s", &encrypt);
}
return 0;
}
When I run it and choose 1 it outputs this:
Enter 1 for Encryption or 2 For Decryption: 1
Enter Plaintext for Encryption: Enter Keyword:
As you can see it doesn't allow the user to input the plaintext and goes right into asking them to enter a keyword.

Look here:
https://stackoverflow.com/a/20156727/14273548
Copied answer to here because of miminum characters.
after this line scanf("%d",&e) add a getchar() like this :
scanf("%d",&e);
getchar();
when you press Enter the newline character stays in the buffer so when fgets is called the newline is passed to it and it actes as if you pressed Enter

scanf() reads exactly what you asked it to, leaving the following \n from the end of that line in the buffer where fgets() will read it. I would recommend using fgets() for reading input too and using sscanf() to read choice integer:
char input[10];
...
fgets(input, 10, stdin);
sscanf(input, "%d", &choice);

Related

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

What is the exact work, that the getchar() is doing? [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 1 year ago.
Here, if I don't use getchar() the output is misbehaving:
What exactly is the getchar() doing here ?
And what is it holding until another input gets invoked ?
And how will the next input be invoked here in this case ?
My code:
//To take 3 students data using stucture which is user defined.
#include<stdio.h>
#include<stdlib.h>
//#include<conio.h>
struct student
{
char reg_number[200];
char name[200];
int marks_obt;
};
int main()
{
struct student stud1,stud2,stud3;
printf("Enter registration number of student 1 : ");
gets(stud1.reg_number);
printf("Enter name of student 1 : ");
gets(stud1.name);
printf("Enter marks of student 1 : ");
scanf("%d",&stud1.marks_obt);
system("cls");
//getchar();
printf("Enter registration number of student 2 : ");
gets(stud2.reg_number);
printf("Enter name of student 2 : ");
gets(stud2.name);
printf("Enter marks of student 2 : ");
scanf("%d",&stud2.marks_obt);
system("cls");
//getchar();
printf("Enter registration number of student 3 : ");
gets(stud3.reg_number);
printf("Enter name of student 3 : ");
gets(stud3.name);
printf("Enter marks of student 3 : ");
scanf("%d",&stud3.marks_obt);
system("cls");
printf("ID of student 1 is %s \n Name of student 1 is %s \n Marks obtained by stdent 1 is %d",stud1.reg_number,stud1.name,stud1.marks_obt);
printf("\n\n");
printf("ID of student 2 is %s \n Name of student 2 is %s \n Marks obtained by stdent 2 is %d",stud2.reg_number,stud2.name,stud2.marks_obt);
printf("\n\n");
printf("ID of student 3 is %s \n Name of student 3 is %s \n Marks obtained by stdent 3 is %d",stud3.reg_number,stud3.name,stud3.marks_obt);
//getch();
}
First of all, never use the gets(). It is deprecated from the C and C++ standards. The safe way would be to apply fgets():
char input[128];
if (fgets(input, sizeof input, stdin) == NULL) {
// Oops... input was incorrectly given, handle the error
return EXIT_FAILURE; // To quit
}
// Removing the trailing newline character
input[strcspn(input, "\n")] = 0;
You're facing an overlap when asking for another input from the user in the next gets() call because you hit the Return key as well when you finish typing with scanf(). A newline key is added at the end.
The getchar() takes the newline, so it is discarded and does the job you expect.
There are already comments and a correct answer that should be enough, but judging by your last comment it seems that you didn't yet understand what's going on.
This line:
scanf("%d",&stud1.marks_obt);
Parses an integer, for that you press Enter, when you do that a \n is added to the stdin buffer, and remains there, it is not parsed by scanf.
After that:
gets(stud2.reg_number);
Will parse that \n character and store it in stud2.reg_number, and the program moves on.
When you use getchar(), it parses the \n and leaves the stdin buffer empty again so the gets has nothing to parse and waits for your input, correcting the problem, it's still a flimsy solution, but it works in this particular case.
Moral of the story, don't mix scanf with gets, fgets at least, since, as stated, gets was removed from the standard in C11. The reason why some compilers still support it is beyond me.

Skipping an Input after scanf() [duplicate]

This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 4 years ago.
In the code below, after the scanf() for newMIn it skips the gets() for newLname. I've tried relocating it to other parts but it still skips, I've also tried using getchar() instead of scanf() but it still skips the next immediate function. All other variables are strings, and this function is part of a larger program.
void getINF(char *newStID, char *newLname, char *newMIn,char *newFname, char *newHomeAdd, char *newCourse, char *newMumNam,char *newPopsNam ){
printf("Input Student ID:\n");
gets(newStID);
printf("Input First Name:\n");
gets(newFname);
printf("Input Middle Initial:\n");
scanf(" %c", &newMIn);
printf("Input Last Name:\n");
gets(newLname);
printf("Input Home Address:\n");
gets(newHomeAdd);
printf("Input Course:\n");
gets(newCourse);
printf("Input Name of Mother:\n");
gets(newMumNam);
printf("Input Name of Father:\n");
gets(newPopsNam);
printf("\n\n%s\n",newStID);
printf("%s\n",newFname);
printf("%c\n",newMIn);
printf("%s\n",newLname);
printf("%s\n",newHomeAdd);
printf("%s\n",newMumNam);
printf("%s\n",newPopsNam);
printf("%s\n",newCourse);
return;
}
When using the %c token with scanf, it will not consume any extra whitespace of newline characters. As such, the newline character after pressing enter is left in the input buffer and then consumed by the following gets call.
Use this popular method to clear the input before the next newline:
int c;
while ((c = getchar()) != '\n' && c != EOF);

Why isn't my %[^\n] not working properly? [duplicate]

This question already has answers here:
scanf: "%[^\n]" skips the 2nd input but " %[^\n]" does not. why?
(6 answers)
The differences of scanf("%[^\n]",name); and scanf(" %[^\n]",name);
(2 answers)
scanf() leaves the newline character in the buffer
(7 answers)
Closed 5 years ago.
int main() {
char a[100];
printf("\nEnter 1st Sentence : ");
scanf("%[^\n]", a);
printf("\nSentence 1 : %s", a);
printf("\nEnter 2nd Sentence : ");
scanf("%[^\n]", a);
printf("\nSentence 2 : %s", a);
return 0;
}
My output:
Enter 1st Sentence : Testing 1st Sentence
Sentence 1 : Testing 1st Sentence
Enter 2nd Sentence :
Sentence 2 : Testing 1st Sentence
I'm basically checking %[^\n]. When I type the 1st sentence and press "Enter" key, it prints "Enter 2nd Sentence : " and then "Sentence 2 : " and then it prints the 1st sentence.
Because you did not read the Enter key from the input buffer, it is still there when the second scanf() asks for input. It then thinks you just pressed enter without typing any text.
Instead of scanf("%[^\n]", a), use this:
fgets(a, sizeof(a), stdin);
And just strip the trailing newline yourself.
There are multiple problems with scanf("%[^\n]", a):
You have a potential buffer overfow if reading a line longer than 99 bytes. You can prevent this with scanf("%99[^\n]", a).
You leave the newline in the input stream and it is still present for the next call where it causes the conversion to fail because the format must match at least one byte different from newline. You can prevent this by ignoring leading white space with scanf(" %[^\n]", a). Note the initial space in the format string.
You do not check if the conversion was successful. scanf() return the number of successful conversions. In your case it should return 1.
Here is the modified program:
#include <stdio.h>
int main(void) {
char a[100];
printf("\nEnter 1st Sentence: ");
if (scanf(" %99[^\n]", a) != 1)
return 1;
printf("\nSentence 1 : %s", a);
printf("\nEnter 2nd Sentence : ");
if (scanf(" %99[^\n]", a) != 1)
return 1;
printf("\nSentence 2 : %s", a);
return 0;
}

Program is skipping fgets without allowing input

Basically as the title says.. When my program is run from the console, it'll ask if you'd like to encrypt or decrypt.. and when I input e or E, it creates a new blank line (until I input some kind of text), then shows the "enter the text" and "enter the key" lines all at once..
So, in the console it would look something like:
Would you like to (E)ncrypt or (D)ecrypt? e
asdf jkl; <---- random user input to get the program to continue..
Enter the text you would like to encrypt : Enter a key to use for encryption : (user input)
and then the program exits..
//message to be encrypted
char text[250];
//word to use as the key
char key[50];
//stores the encrypted word
char encrypted[250];
char answer;
printf("Would you like to (E)ncrypt or (D)ecrypt? ");
scanf(" %c", &answer);
if(answer == 'e' || answer == 'E')
{
printf("Enter the text you want to encrypt : ");
fgets(text, 250, stdin);
printf("Enter a key to use for encryption : ");
fgets(key, 50, stdin);
printf("Encrypted text : ");
//code that encrypts the text here
}
So the problem, then, is that it's skipping the fgets entirely and not waiting/allowing the user to input any answers.. why for?
The line scanf(" %c", &answer); is leaving a newline in the input buffer which is taken by fgets. The leading space in " %c" consumes leading whitespace but not trailing whitespace.
You can get rid of the newline with the "%*c" format specifier in scanf which reads the newline but discards it. No var argument needs to be supplied.
#include <stdio.h>
int main(void)
{
char answer;
char text[50] = {0};
scanf(" %c%*c", &answer);
fgets(text, sizeof text, stdin);
printf ("%c %s\n", answer, text);
return 0;
}
From http://www.cplusplus.com/reference/cstdio/fgets/
"Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first."
Presumably you press Enter after typing E or D. Your scanf() doesn't consume the newline so it remains in the input stream. fgets() sees the newline and returns.

Resources