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

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

Related

Why isn't this simple code waiting for student name (entered by user)? [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 1 year ago.
This C code is not waiting for student name. It directly prints total student number. But when I comment out the first printf-scanf statement(or enter number of students:), then code is waiting for the user to enter student name.
#include <stdio.h>
int main()
{
char name[10];
int count;
printf("ENTER NUMBER OF STUDENTS:\n");
scanf("%d", &count);
printf("ENTER STUDENT NAME:\n");
scanf("%[^\n]%*c", &name);
printf("Total_Students: %d\n", count);
printf("NAME: %s\n", name);
return (0);
}
The second scanf is skipped because the newline character is being interpreted from the first scanf.
For instance, if you entered 2 for number of student, what is being entered is 2\n. The first scanf reads the number 2 and leaves the \n in the buffer which is being interpreted by the 2nd scanf.
You can simply add a space in the second scanf to get past this issue
scanf(" %[^\n]%*c", &name);
change the second scanf() argument to %s and it directly makes the last entry as NULL
.

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.

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

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

How to prompt the user to enter an integer and a character from the keyboard in C [duplicate]

This question already has an answer here:
How to read / parse input in C? The FAQ
(1 answer)
Closed 4 years ago.
I am trying to figure out the best way to get an integer and a character from a user
Here is what I have so far:
#include <stdio.h>
int main()
{
int a;
char b;
printf("enter the first number: \n");
scanf("%d", &a);
printf("enter the second char: \n");
scanf("%c", &b);
printf("Number %d",a);
printf("Char %c",b);
return 0;
}
The output is not shown correctly. Is there any problem with this?
Your input and output statements are fine. Just replace printf("Number %d",a); with printf("Number %d\n",a); to better format the output. Also you should change your second scanf statement to scanf(" %c", &b);. This will deal with the newline character entered after the number is inputted.
After you enter the number, you pressed the Enter key. Since the scanf function works on the input stream, when you try to process the next char after reading the number, you are not reading the character you typed, but the '\n' character preceding that. (i.e. because the Enter key you pressed added a '\n' character to your input stream, before you typed your char)
You should change your second call to scanf with the following.
scanf(" %c", &b);
Notice the added space character in the formatting string. That initial space in the formatting string helps skip any whitespace in between.
Additionally, you may want to add \n at the end of the formatting strings of both printf calls you make, to have a better output formatting.
Here you need to take care of hidden character '\n' , by providing the space before the %c in scanf() function , so the "STDIN" buffer will get cleared and scanf will wait for new character in "STDIN" buffer .
modify this statement in your program : scanf("%c",&b); to scanf(" %c",&b);

scanf is being skipped in C [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 5 years ago.
I tried to run the following program:
int main(){
char a;
char b;
char c;
printf("\nenter a: ");
scanf("%c", &a);
printf("\nenter b: ");
scanf("%c", &b);
printf("\nenter c: ");
scanf("%c", &c);
return 0;
}
upon running the program it prompts you to enter a value for a. once you do, you are prompted to enter a value for b, however you are not allowed to input a value because the program skips the scan and then prompts you again to input a value for c which is not skipped. I can initialize a and c, but not b. and I have no idea why. I read somewhere that using %[^\n] in the scanf, but I tried using it and I don't think I used it correctly because it still wasn't working.
this is the output (with some input examples):
enter a: 1
enter b:
enter c: 1
process returned 0 (0x0)
Instead of "%c", use " %c".
Without the space, scanf does not skip white spaces when the format specifier is %c. That is initially confusing since it will skip white spaces for other format specifiers, such as %d, %f, %s, etc.
When you press enter, that adds a character to the input queue, which is then read into b.
You can either explicitly read a character to ignore it, or you can use (for one alternative) %1s to read a single-character string (which will skip white-space, including the new-line character entered when you press enter.
'\n' becomes the input for variable b after you press enter.
so to take care of this, use getchar() which will take care of '\n'.
int main(){
char a;
char b;
char c;
printf("\nenter a: ");
scanf("%c", &a);
getchar();
printf("\nenter b: ");
scanf("%c", &b);
getchar();
printf("\nenter c: ");
scanf("%c", &c);
return 0;
}

Resources