I got an error reading a character on C [duplicate] - c

This question already has answers here:
Why does scanf ask twice for input when there's a newline at the end of the format string?
(7 answers)
Closed 5 years ago.
I want to read a single character from the console, but when I do, the program reads characters yet and I must write another character to save the first and finish its execution.
Code:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
char peps;
int main(int argc, char const *argv[]) {
printf("write a character:\n");
scanf(" %c\n", &peps);
printf("%c\n", peps);
return 0;
}
Can anyone explain why it does that and how to correct this error?

If you remove the \n from the scanf(), it should work as you want.
ie, do
scanf(" %c", &peps);
instead of
scanf(" %c\n", &peps);
This is because the \n in the scanf() format string is telling the computer to read and ignore all white spaces (including \n) after reading a character.
So all white spaces including the newlines given by typing the enter key, would be ignored. This will stop only when a non-white space character is encountered which won't be read and would thus remain in the input buffer.
So, in your case, a character would first be read and it would wait for a non-white space character before executing the printf() following the scanf(). The non-white space character would remain in the input buffer and was not read and is hence not printed at once. It would be read only upon reading from the stdin again.
If you want to explore this further, consider placing that scanf() and printf() in a loop and examine the output.
Note that replacing that \n with a space would have the same effect.
ie,
scanf(" %c\n", &peps);
and
scanf(" %c ", &peps);
would have the same behavior.
What's the behavior of scanf when the format string ends with a newline?
Behaviour of scanf when newline is in the format string

Related

Why does the 2nd iteration not execute the expected printf in the loop and even takes one extra input to show the final output? [duplicate]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *method1(void)
{
static char a[4];
scanf("%s\n", a);
return a;
}
int main(void)
{
char *h = method1();
printf("%s\n", h);
return 0;
}
When I run the code above, the prompt is asking me twice for input (I only use scanf once in the code). Why is that?
(I entered 'jo'; it asked for more input, so I entered 'jo' again. Then it only printed out 'jo' once.)
From my scanf manual page
White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input. Everything else matches only itself.
Thus with scanf ("%s\n", a) it will scan for a string followed by optional white space. Since after the first newline more whitespace may follow, scanf is not done after the first newline and looks what's next. You will notice that you can enter any number of newlines (or tabs or spaces) and scanf will still wait for more.
However, when you enter the second string, the sequence of whitespace is delimited and scanning stops.
Use scanf ("%s", a) to not scan trailing whitespace.
you have to remove the \n from the string format of the scanf. It should be
scanf("%s",a);
EDIT: Explanation
the %s means that the scanf reads the input character till it gets a delimiter which should be a white space like space or tab or new line(\n) so the first enter is get as a delimiter for the "%s" and adding the "\n" to the string format "%s\n" means that the scanf will wait 2 newlines the first newline is related to the delimiter of the "%s" and the second newline is related to the\n of the string format.
Remove \n from the scanf format and give an input and it displays the output based on the given output once.
you can use either of these to avoid the mentioned problem :
scanf("%s",a);
or
scanf("\n%s",a);
Try this: Don't use \n on scanf, it won't ask you twice and sometimes it might show an error
Your code: scanf("%s\n", a);
Try this on scanf: scanf("%s", a);
use gets() or fgets() instead...alternatively use scanf("%[^\n]s",a);
Don't use the escape sequence in scanf stdio function
scanf ("%s", a);

New to coding an need help figuring out why certain portions aren't working as they should be [duplicate]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *method1(void)
{
static char a[4];
scanf("%s\n", a);
return a;
}
int main(void)
{
char *h = method1();
printf("%s\n", h);
return 0;
}
When I run the code above, the prompt is asking me twice for input (I only use scanf once in the code). Why is that?
(I entered 'jo'; it asked for more input, so I entered 'jo' again. Then it only printed out 'jo' once.)
From my scanf manual page
White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input. Everything else matches only itself.
Thus with scanf ("%s\n", a) it will scan for a string followed by optional white space. Since after the first newline more whitespace may follow, scanf is not done after the first newline and looks what's next. You will notice that you can enter any number of newlines (or tabs or spaces) and scanf will still wait for more.
However, when you enter the second string, the sequence of whitespace is delimited and scanning stops.
Use scanf ("%s", a) to not scan trailing whitespace.
you have to remove the \n from the string format of the scanf. It should be
scanf("%s",a);
EDIT: Explanation
the %s means that the scanf reads the input character till it gets a delimiter which should be a white space like space or tab or new line(\n) so the first enter is get as a delimiter for the "%s" and adding the "\n" to the string format "%s\n" means that the scanf will wait 2 newlines the first newline is related to the delimiter of the "%s" and the second newline is related to the\n of the string format.
Remove \n from the scanf format and give an input and it displays the output based on the given output once.
you can use either of these to avoid the mentioned problem :
scanf("%s",a);
or
scanf("\n%s",a);
Try this: Don't use \n on scanf, it won't ask you twice and sometimes it might show an error
Your code: scanf("%s\n", a);
Try this on scanf: scanf("%s", a);
use gets() or fgets() instead...alternatively use scanf("%[^\n]s",a);
Don't use the escape sequence in scanf stdio function
scanf ("%s", a);

what is the wrong in using two scanf(%s) simultaneously [duplicate]

This question already has answers here:
scanf: "%[^\n]" skips the 2nd input but " %[^\n]" does not. why?
(6 answers)
Closed 6 years ago.
why second scanf doesnt take any input ? does %s cancatanae the string?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char string1[50];
char string2[50];
scanf("%[^\n]s",string1);
scanf("%[^\n]s",string2);
printf("\nfirst string :%s \n",string1);
printf("\nsecnd string :%s \n",string2);
return 0;
}
input : this is bbc [enter]
output: first string :this is bbc
second string:{some characters symbol}
"%[^\n]s" tells to scanf to "eat" all the character that aren't a newline and put them in the argument; this means that, after the first scanf returns, it is leaving the newline that made it stop in the read buffer. The next scanf finds it and immediately stops reading - after all, you told it to read up to the first newline!
A solution here can be to use "%[^\n]s\n", which "eats" even the newline that follows the string, or even "%[^\n]s ", where the space is "magic", in that it tells scanf to eat all the other whitespace it can find, which includes newlines (notice however that this is a bad idea if you want to be able to read an empty string in the next line).
Even simpler, you can simply use fgets(string1, sizeof(string1), stdin), which, unlike scanf with %s, is safe against buffer overflows (yes, you can make even %s safe, but it's more work). Notice that fgets puts even the trailing newline into your string.
The problem is that your scanf format string requires the string to end in s: %[^\n] is interpreted as the format specifier, and then you have an s which must be matched by the input. Since the second string does not start in s, the second scanf reads nothing.
Replacing s with a space will fix the problem:
scanf("%[^\n] ", string1);
// ^
// Space is important
Even better, put space in front of %[^\n] in the second scanf:
scanf("%49[^\n]", string1);
scanf(" %49[^\n]", string2);
Since your string buffers have limited capacity, putting a limit of 49 is necessary to avoid buffer overruns.
Your code will only read one input. As %[^\n]s fails to read an 's'
Replace two scanf() statement with following one.
Just executed your code on my system it works.
scanf("%[^\n]s %[^\n]s",string1,string2);
Or just remove s from your statements and add space.
scanf("%[^\n] ",string1);
scanf("%[^\n] ",string2);
checked with your input for both the string and it displays the proper output.

Reading newline from previous input when reading from keyboard with scanf()

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?
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.
What you're seeing is the correct behavior of the functions you call:
scanf will read one word from the input, and leave the input pointer immediately after the word it reads. If you type computer<RETURN>, the next character to be read is the newline.
To read a whole line, including the final newline, use fgets. Read the documentation carefully: fgets returns a string that includes the final newline it read. (gets, which shouldn't be used anyway for a number of reasons, reads and discards the final newline.)
I should add that while scanf has its uses, using it interactively leads to very confusing behavior, as I think you discovered. Even in cases where you want to read word by word, use another method if the intended use is interactive.
You can make use of %*c:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s%*c", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c%*c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
%*c will accept and ignore the newline or any white-spaces
You cal also put getchar() after the scanf line. It will do the job :)
The streams need to be flushed. When performing successive inputs, the standard input stream, stdin, buffers every key press on the keyboard. So, when you typed "computer" and pressed the enter key, the input stream absorbed the linefeed too, even though only the string "computer" was assigned to string. Hence when you scanned for a character later, the already loaded new line character was the one scanned and assigned to character.
Also the stdout streams need to be flushed. Consider this:
...
printf("foo");
while(1)
{}
...
If one tries to execute something like this then nothing is displayed on the console. The system buffered the stdout stream, the standard output stream, unaware of the fact it would be encounter an infinite loop next and once that happens, it never gets a chance to unload the stream to the console.
Apparently, in a similar manner whenever scanf blocks the program and waits on stdin, the standard input stream, it affects the other streams that are buffering. Anyway, whatsoever may be the case it's best to flush the streams properly if things start jumbling up.
The following modifications to your code seem to produce the desired output
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
fflush(stdout);
scanf ("%s", string);
fflush(stdin);
printf ("%s", string);
printf ("\nwrite a character: ");
fflush(stdout);
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
Output:
write something: computer
computer
write a character: a
Character a Correspondent number: 97

Difference between scanf("%c", &c) and scanf(" %c", &c) [duplicate]

This question already has answers here:
Why does a space in my scanf statement make a difference? [duplicate]
(3 answers)
Closed 9 years ago.
Consider the following C code snippet:
#include <stdio.h>
int main()
{
int a;
char c;
scanf("%d",&a);
scanf("%c",&c);
printf("int=%d\n",a);
printf("char=%c\n",c);
}
I'm able to input only the integer and not the character.The output is simply the integer value and no value is output for the second printf statement.
However if I use a space before the format specifier:
scanf(" %c",&c);
It works as expected. Why is this the case?
Someone told me it has something to do with clearing the input buffer. Could someone shed some light on the same?
The difference between scanf("%c", &c1) and scanf(" %c", &c2) is that the format without the blank reads the next character, even if it is white space, whereas the one with the blank skips white space (including newlines) and reads the next character that is not white space.
In a scanf() format, a blank, tab or newline means 'skip white space if there is any to skip'. It does not directly 'clear the input buffer', but it does eat any white space which looks similar to clearing the input buffer (but is quite distinct from that). If you're on Windows, using fflush(stdin) clears the input buffer (of white space and non-white space characters); on Unix and according to the C standard, fflush(stdin) is undefined behaviour.
Incidentally, if you typed the integer followed immediately by a carriage return, the output of your program ends with two newlines: the first was in c and the second in the format string. Thus, you might have seen:
$ ./your_program
123
int=123
char=
$
That is, the scanf() reads the newline as its input. Consider an alternative input:
$ ./your_program
123xyz
int=123
char=x
$
The integer input stopped when it read the 'x'; the character input therefore reads the 'x'.
Because after you input the number and press ENTER, the new line stays in the buffer and will be processed by the second scanf.
In short, you saved new line in the variable c.
However ,if you use
scanf(" %c",&c);
// ^
the space will consume the new line, which makes c the value you expected.
You have to pass a pointer to the data object specified by the format string, so
scanf("%c", c);
will actually pass the value of c, which in turn could cause a program fault,
scanf("%c", &c);
will pass the address of c, allowing scanf to change the value of your copy.
The space after the %c will force it to look for a character, AND THEN a space. If there is not a space, it will not read the character

Resources