I tried this code below, but it seems scanf("%c") is skipped. It only asks me to enter name and age and skips the lines below that. It just print the text in the printf above the if statements. Can anyone help?
#include<stdio.h>
int main()
{
int age;
char sex;
char name[20];
char status;
printf("Enter your last name\n");
scanf("%s", &name);
printf("Enter your age\n");
scanf("%d", &age);
printf("Enter sex (M/F)\n");
scanf("%c", &sex);
printf("your status,married, single,irrelevant (M/S/I)\n");
scanf("%c", &status);
if(age>=16 && sex=='M')
printf("hello, Mr %s\n", name);
if(age<16 && sex =='M')
printf("hello, Master %s\n", name);
if(sex=='F' && status=='M')
printf("hello, Mrs %s\n", name);
if(sex=='F' &&(status=='S' ||status=='I'))
printf("hello,miss %s\n", name);
}
Change
scanf("%c", &sex);
to
scanf(" %c", &sex);
^
space
and
scanf("%c", &status);
to
scanf(" %c", &status);
^
space
The problem is because of trailing newline characters after your second call to scanf(). Since it is of %d type specifier, when you press Enter A newline character ( '\n' ) is left in the stream and the next scanf() tries to read that newline character, and thus, it seems as though it just skipped input, but in fact, it read the newline character.
So, the newline character is stored in the variable sex, and thus, it skips asking you for input for that variable.
Unless you are interested in whitespace like newlines, do not use %c. Simply use the string conversion %s and use the first character of the input.
Rationale: All scanf conversion specifiers except %c ignore white space including newlines. They are designed to read sequences of input tokens (numbers, words) where the amount and nature of white space is irrelevant. The words can all be on the same line, or each word on a different line; scanf wouldn't care unless you force single character reads with %c which is almost never necessary.
Change your code to
#include<stdio.h>
int main()
{
int age;
char sex;
char name[20];
char status;
printf("Enter your last name\n");
// scanf("%s", &name);
fgets(name,20,stdin);
printf("Enter your age\n");
scanf("%d", &age);
printf("Enter sex (M/F)\n");
scanf(" %c", &sex);
printf("your status,married, single,irrelevant (M/S/I)\n");
scanf(" %c", &status);
if(age>=16 && sex=='M')
printf("hello, Mr %s\n", name);
if(age<16 && sex =='M')
printf("hello, Master %s\n", name);
if(sex=='F' && status=='M')
printf("hello, Mrs %s\n", name);
if(sex=='F' &&(status=='S' ||status=='I'))
printf("hello,miss %s\n", name);
return 0;
}
Here, I have added an extra space before the format specifier %c, to accommodate any previous input like newline (\n). Another alternative method is to use getchar() immediately before you take any character input.
Also, if you perform string input with scanf, it will not read the input after encountering a whitespace. So, instead use fgets for taking any string input which might contain spaces.
Another thing I changed in your code (trivial) is int main() and return 0.
This happens because blankspace is also treated as a character and and happens when you press enter.
So Leave a space.
scanf(" %c",&something);
You can do the following for all scanfs.
scanf("%c\n",&smth);
And then enter the values one by one separating them by newlines (press Enter).
This helped me too when I had the same problem.
scanf("%c*",&smth);
That makes scanf skip any other characters that a user might input, including newlines.
Note: use appropriate format strings for each type (%s for strings, %d for integers, etc).
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
In C:
I'm trying to get char from the user with scanf and when I run it the program don't wait for the user to type anything...
This is the code:
char ch;
printf("Enter one char");
scanf("%c", &ch);
printf("%c\n",ch);
Why is not working?
The %c conversion specifier won't automatically skip any leading whitespace, so if there's a stray newline in the input stream (from a previous entry, for example) the scanf call will consume it immediately.
One way around the problem is to put a blank space before the conversion specifier in the format string:
scanf(" %c", &c);
The blank in the format string tells scanf to skip leading whitespace, and the first non-whitespace character will be read with the %c conversion specifier.
First of all, avoid scanf(). Using it is not worth the pain.
See: Why does everyone say not to use scanf? What should I use instead?
Using a whitespace character in scanf() would ignore any number of whitespace characters left in the input stream, what if you need to read more inputs? Consider:
#include <stdio.h>
int main(void)
{
char ch1, ch2;
scanf("%c", &ch1); /* Leaves the newline in the input */
scanf(" %c", &ch2); /* The leading whitespace ensures it's the
previous newline is ignored */
printf("ch1: %c, ch2: %c\n", ch1, ch2);
/* All good so far */
char ch3;
scanf("%c", &ch3); /* Doesn't read input due to the same problem */
printf("ch3: %c\n", ch3);
return 0;
}
While the 3rd scanf() can be fixed in the same way using a leading whitespace, it's not always going to that simple as above.
Another major problem is, scanf() will not discard any input in the input stream if it doesn't match the format. For example, if you input abc for an int such as: scanf("%d", &int_var); then abc will have to read and discarded. Consider:
#include <stdio.h>
int main(void)
{
int i;
while(1) {
if (scanf("%d", &i) != 1) { /* Input "abc" */
printf("Invalid input. Try again\n");
} else {
break;
}
}
printf("Int read: %d\n", i);
return 0;
}
Another common problem is mixing scanf() and fgets(). Consider:
#include <stdio.h>
int main(void)
{
int age;
char name[256];
printf("Input your age:");
scanf("%d", &age); /* Input 10 */
printf("Input your full name [firstname lastname]");
fgets(name, sizeof name, stdin); /* Doesn't read! */
return 0;
}
The call to fgets() doesn't wait for input because the newline left by the previous scanf() call is read and fgets() terminates input reading when it encounters a newline.
There are many other similar problems associated with scanf(). That's why it's generally recommended to avoid it.
So, what's the alternative? Use fgets() function instead in the following fashion to read a single character:
#include <stdio.h>
int main(void)
{
char line[256];
char ch;
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
ch = line[0];
printf("Character read: %c\n", ch);
return 0;
}
One detail to be aware of when using fgets() will read in the newline character if there's enough room in the inut buffer. If it's not desirable then you can remove it:
char line[256];
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
line[strcpsn(line, "\n")] = 0; /* removes the trailing newline, if present */
This works for me try it out
int main(){
char c;
scanf(" %c",&c);
printf("%c",c);
return 0;
}
Here is a similiar thing that I would like to share,
while you're working on Visual Studio you could get an error like:
'scanf': function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS
To prevent this, you should write it in the following format
A single character may be read as follows:
char c;
scanf_s("%c", &c, 1);
When multiple characters for non-null terminated strings are read, integers are used as the width specification and the buffer size.
char c[4];
scanf_s("%4c", &c, _countof(c));
neither fgets nor getchar works to solve the problem.
the only workaround is keeping a space before %c while using scanf
scanf(" %c",ch); // will only work
In the follwing fgets also not work..
char line[256];
char ch;
int i;
printf("Enter a num : ");
scanf("%d",&i);
printf("Enter a char : ");
if (fgets(line, sizeof line, stdin) == NULL) {
printf("Input error.\n");
exit(1);
}
ch = line[0];
printf("Character read: %c\n", ch);
try using getchar(); instead
syntax:
void main() {
char ch;
ch = getchar();
}
Before the scanf put fflush(stdin); to clear buffer.
The only code that worked for me is:
scanf(" %c",&c);
I was having the same problem, and only with single characters. After an hour of random testing I can not report an issue yet. One would think that C would have by now a bullet-proof function to retrieve single characters from the keyboard, and not an array of possible hackarounds... Just saying...
Use string instead of char
like
char c[10];
scanf ("%s", c);
I belive it works nice.
Provides a space before %c conversion specifier so that compiler will ignore white spaces. The program may be written as below:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ch;
printf("Enter one char");
scanf(" %c", &ch); /*Space is given before %c*/
printf("%c\n",ch);
return 0;
}
You have to use a valid variable. ch is not a valid variable for this program. Use char Aaa;
char aaa;
scanf("%c",&Aaa);
Tested and it works.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char firstname[15];
char lastname[15];
char crush_first[15];
char crush_last[15];
int babies;
printf("What is your first name?\n");
scanf("%s", firstname );
printf("What is your last name?\n");
scanf(" %s", lastname);
/* see i have added space before the character conversion but on exectution
of this file no space is in between the two strings*/
printf("What is your crush's first name?\n");
scanf("%s", crush_first );
printf("What is your crush's last name?\n");
scanf(" %s", crush_last );
printf("How many kids will you have?");
scanf("%d", &babies );
printf("%s%s will have a lovely marriage with %s%s and they will have %d kids",firstname,lastname,crush_first,crush_last,babies);
}
now here i want to do is to add space by default in the string. "__etc" i want the string to also store these values . Though i have added space before %s repeatedly but it is not recognizing.
From scanf doc:
s matches a sequence of non-whitespace characters (a string) [...]
Also if someone enters string longer then your receive buffer, you will overflow the buffer.
Maybe use fgets if you want to read the line up until a newline:
fgets(lastname, sizeof(lastname), stdin);
I am trying to have the user enter for the first, middle, and last name in my struct. The first scan works fine, any after that do not work. Here's my code so far
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "contacts.h"
int main (void)
{
// Declare variables here:
struct Name names;
char yesNo;
// Display the title
printf("Contact Management System\n");
printf("-------------------------\n");
// Contact Name Input:
printf("Please enter the contact's first name: ");
scanf ("%d", &names.firstName);
printf("Do you want to enter a middle initial(s)? (y or n): ");
scanf(" %c", &yesNo);
while (yesNo == 'y' || yesNo == 'Y') {
printf("Please enter the contact's middle initial(s): ");
scanf(" %c%d", &names.middleInitial);
yesNo = 'n';
}
printf("Please enter the contact's last name: ");
scanf(" %c%d", &names.lastName);
Here's the struct in my header file
struct Name {
char firstName[31];
char middleInitial[7];
char lastName[36];
};
When I enter more than one character the program ends, when I enter just one character, the program skips the second scanf. I had the program working beforehand but I realized I needed to use structs so I switched from int's to the struct, and I haven't been able to make it work this way.
You are using scanf wrong.
scanf ("%d", &names.firstName);
names.firstName is a char array, but you are using %d which expects a
pointer to int, you are passing a pointer to an array. This is correct:
scanf("%30s", names.firstName);
Then you do
scanf(" %c%d", &names.middleInitial);
which has two errors: you are giving two conversion but passing only a on
pointer, and you are again passing the wrong pointer. Correct:
scanf("%6s", names.middleInitial);
and the same applies for scanf(" %c%d", &names.lastName);, the correct version
scanf("%35s", names.lastName);
In general, when using scanf with %s, you will have the problem that newline
and other strings are kept in the input buffer. This happens because %s
matches a sequence of non-white-space characters, so the newline (entered when
ENTER is pressed) will remain in the input buffer. Another example is
if the user enters two word separated by at least an empty space (like Hello Word),
%s would only read Hello. Subsequent calls of scanf may fail if they don't
anticipate this. That's why the best strategy is to clean the
buffer, use this function:
void clean_file_buffer(FILE *fp)
{
int c;
while((c = fgetc(fp)) != '\n' && c!=EOF);
}
And the you can use it like this:
printf("Please enter the contact's first name: ");
scanf ("%30s", names.firstName);
clean_file_buffer(stdin);
that takes care of left overs.
If you however want to have more control over the whole line, then you should
use fgets instead to read the whole line and then you can use sscanf to
parse it.
scanf("%s", names.firstName);
scanf(" %c", &yesNo);
scanf(" %s", names.middleInitial);
scanf(" %s", names.lastName);
or
scanf("%s", names.firstName);
getchar();
scanf("%c", &yesNo);
getchar();
scanf("%s", names.middleInitial);
getchar();
scanf("%s", names.lastName);
getchar();
and when yesNo question, if you typed over 1 character, first character will be into yesNo variable, and other chars will be into next input variable(names.middleInitial).
If you want to check the yesNo more carefully,
input yesNo as string. (but, buffer size check needed. buffer overflow.)
char yesNos[100];
scanf(" %s", &yesNos) ;
if ( yesNos[0]=='y' ) {...}
Here first gets() is not working. if I add one more gets() function then from the two last one goes to work. how can I fix it?
CODE
#include<stdio.h>
#include<string.h>
int main(void)
{
short int choice;
char number[15];
do{
printf("\n\nAnswer: ");
scanf("%hd",&choice);
printf("\n");
if(choice==1)
{
printf("Enter the decimal number: ");
gets(number);
}
else
{
printf("Wrong input!.");
system("pause");
system("cls");
}
}while(choice!=1);
return 0;
}
Because the when the user pressed the enter key to give you the input for the scanf call, the enter key added a newline in the input buffer. And the gets call read that newline as an empty line.
One way to solve it is to use fgets to read the first input too, and use sscanf to parse it to a number:
...
printf("\n\nAnswer: ");
char input[64];
fgets(input, sizeof(input), stdin);
sscanf(input, "%hd", &choice);
printf("\n");
...
This make sure that the newline after the input is read and skipped.
Another way is to read one character at a time in a loop after the scanf call, until you have read the newline:
scanf("%hd", &choice);
int ch;
while ((ch = fgetc(stdin)) != EOF && ch != '\n')
{
// Empty
}
And a third way is to simply ask the scanf call to read and ignore white-space after the input:
scanf("%hd ", &choice);
// ^
// |
// Note space here
All of these methods have both pros and cons. You can try them all and use the one that works for you.
You need to skip the whitespace (i.e. the newline) following the number in the input buffer. This can be done by modifying the scanf to:
scanf("%hd ",&choice);
And use fgets(), since gets() is prone to buffer overflows.
I tried this code below, but it seems scanf("%c") is skipped. It only asks me to enter name and age and skips the lines below that. It just print the text in the printf above the if statements. Can anyone help?
#include<stdio.h>
int main()
{
int age;
char sex;
char name[20];
char status;
printf("Enter your last name\n");
scanf("%s", &name);
printf("Enter your age\n");
scanf("%d", &age);
printf("Enter sex (M/F)\n");
scanf("%c", &sex);
printf("your status,married, single,irrelevant (M/S/I)\n");
scanf("%c", &status);
if(age>=16 && sex=='M')
printf("hello, Mr %s\n", name);
if(age<16 && sex =='M')
printf("hello, Master %s\n", name);
if(sex=='F' && status=='M')
printf("hello, Mrs %s\n", name);
if(sex=='F' &&(status=='S' ||status=='I'))
printf("hello,miss %s\n", name);
}
Change
scanf("%c", &sex);
to
scanf(" %c", &sex);
^
space
and
scanf("%c", &status);
to
scanf(" %c", &status);
^
space
The problem is because of trailing newline characters after your second call to scanf(). Since it is of %d type specifier, when you press Enter A newline character ( '\n' ) is left in the stream and the next scanf() tries to read that newline character, and thus, it seems as though it just skipped input, but in fact, it read the newline character.
So, the newline character is stored in the variable sex, and thus, it skips asking you for input for that variable.
Unless you are interested in whitespace like newlines, do not use %c. Simply use the string conversion %s and use the first character of the input.
Rationale: All scanf conversion specifiers except %c ignore white space including newlines. They are designed to read sequences of input tokens (numbers, words) where the amount and nature of white space is irrelevant. The words can all be on the same line, or each word on a different line; scanf wouldn't care unless you force single character reads with %c which is almost never necessary.
Change your code to
#include<stdio.h>
int main()
{
int age;
char sex;
char name[20];
char status;
printf("Enter your last name\n");
// scanf("%s", &name);
fgets(name,20,stdin);
printf("Enter your age\n");
scanf("%d", &age);
printf("Enter sex (M/F)\n");
scanf(" %c", &sex);
printf("your status,married, single,irrelevant (M/S/I)\n");
scanf(" %c", &status);
if(age>=16 && sex=='M')
printf("hello, Mr %s\n", name);
if(age<16 && sex =='M')
printf("hello, Master %s\n", name);
if(sex=='F' && status=='M')
printf("hello, Mrs %s\n", name);
if(sex=='F' &&(status=='S' ||status=='I'))
printf("hello,miss %s\n", name);
return 0;
}
Here, I have added an extra space before the format specifier %c, to accommodate any previous input like newline (\n). Another alternative method is to use getchar() immediately before you take any character input.
Also, if you perform string input with scanf, it will not read the input after encountering a whitespace. So, instead use fgets for taking any string input which might contain spaces.
Another thing I changed in your code (trivial) is int main() and return 0.
This happens because blankspace is also treated as a character and and happens when you press enter.
So Leave a space.
scanf(" %c",&something);
You can do the following for all scanfs.
scanf("%c\n",&smth);
And then enter the values one by one separating them by newlines (press Enter).
This helped me too when I had the same problem.
scanf("%c*",&smth);
That makes scanf skip any other characters that a user might input, including newlines.
Note: use appropriate format strings for each type (%s for strings, %d for integers, etc).