This was supposed to be very simple, but I'm having trouble to read successive inputs from the keyboard.
Here's the code:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
What is happening
When I enter a string (e.g.: computer), the program reads the newline ('\n'
) and puts it in character
. Here is how the display looks like:
write something: computer
computer
Character:
Correspondent number: 10
Moreover, the program does not work for strings with more than one word. How could I overcome these problems?
For a simple solution, you could add a space before the format specifier when you use scanf(), for example: scanf(" %c", &ch); The leading space tells scanf() to skip any whitespace characters (including newline) before reading the next character, resulting in the same behavior as with the other format specifiers.
We can make scanf() to read a new line by using an extra \n, i.e., scanf(“%d\n”, &x) . In fact scanf(“%d “, &x) also works (Note the extra space). We can add a getchar() after scanf() to read an extra newline.
An '\n' - or any whitespace character - in the format string consumes an entire (possibly empty) sequence of whitespace characters in the input.
The secret to getting scanf to perform this way is to put a blank in the format string before the %c format specifier. The blank tells scanf to skip white space and it will actually skip any number of white space characters before reading and storing a character.
First scanf
read the entered string and left behind \n
in the input buffer. Next call to scanf
read that \n
and store it to character
.
Try this
scanf (" %c", &characte);
// ^A space before %c in scanf can skip any number of white space characters.
Program will not work for strings more than one character because scanf
stops reading once find a white space character. You can use fgets
instead
fgets(string, 200, stdin);
OP's first problem is typically solved by prepending a space to the format. This will consume white-space including the previous line's '\n'
.
// scanf("%c", &character);
scanf(" %c", &character);
Moreover, the program does not work for strings with more than one word. How could I overcome these problems?
For the the 2nd issue, let us go for a more precise understanding of "string" and what "%s"
does.
A string is a contiguous sequence of characters terminated by and including the first null character. 7.1.1 1
OP is not entering a string even though "I enter a string (e.g.: computer)," is reported. OP is entering a line of text. 8 characters "computer" followed by Enter. There is no "null character" here. Instead 9 char
"computer\n"
.
"%s"
in scanf("%s", string);
does 3 things:
1) Scan, but not save any leading white-space.
2) Scan and save into string
any number of non-white-space.
3) Stop scanning when white-space or EOF reached. That char
is but back into stdin
. A '\0'
is appended to string
making that char
array a C string.
To read a line including spaces, do not use scanf("%s",...
. Consider fgets()
.
fgets(string, sizeof string, stdin);
// remove potential trailing \r\n as needed
string[strcspn(string, "\n")] = 0;
Mixing scanf()
and fgets()
is a problem as calls like scanf("%s", string); fgets(...)
leave the '\n'
in stdin
for fgets()
to read as a line consisting of only "\n"
. Recommend instead to read all user input using fgets()
(or getline()
on *nix system). Then parse the line read.
fgets(string, sizeof string, stdin);
scanf(string, "%c", &character);
If code must user scanf()
to read user input including spaces:
scanf("%*[\n]"); // read any number of \n and not save.
// Read up to 199 `char`, none of which are \n
if (scanf("%199[^\n]", string) != 1) Handle_EOF();
Lastly, code should employ error checking and input width limitations. Test the return values of all input functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With