scanf and newlines in c [duplicate] - c

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Closed 6 years ago.
I just had a test in my C class today and I have reason to believe that answer might be incorrect.
scanf("%d\n", &x); // Evaluate the expression for the string "54321\n"
The idea is pretty simplistic. Find an integer and place the scanned number at the memory location corresponding with integer variable x. However, I don't believe that this call to scanf would ever terminate.
As far as I am concerned, all calls to scanf to standard I/O terminate with the press of the enter key, so there is no need to include the newline in the specifier string. In fact, this redundancy will only cause the program to stall in search of something that will never match the string.
Is there anyone who can clarify the technicalities of the scanf function to put this problem to rest?

I don't believe that this call to scanf would ever terminate.
6 character input like "54321\n" is insufficient to cause this scanf("%d\n", &x); to return. The program stalls. Something else must yet occur.
'\n' directs scanf() to consume white-spaces and to do so until
a non-white-space is detected.
stdin is closed
An input error occurs on stdin (rare).
As stdin is usually line buffered, scanf() receives data in chunks.
The first chunk 123Enter is not enough to cause scanf("%d\n", &x); to return. One of the 3 above needs to happen.
Any following input with some non-white-space fulfills #1, be it:
456Enter or
xyzEnter or
EnterEnter$Enter or ...
Then scanf() will return with a 1 indicate a value, 123, was stored in x. The 4, x or $ above was the non-white-space detected that caused completion. That character will be the next character read by subsequent input on stdin.
scanf("%d\n", &x); is almost certainly the wrong code to use as it obliges another line of user input and does not check its return value.

all calls to scanf to standard I/O terminate with the press of the enter key, so there is no need to include the newline in the specifier string.
That's correct. The \n in the format string will ignore any number of whitespaces, including the "ENTER" key; so, you'll have to input a non-whitespace char to terminate the scanf() call. So, yes, the \n is problematic.
scanf()'s man page says:
· A sequence of white-space characters (space, tab, newline,
etc.; see isspace(3)). This directive matches any amount of
white space, including none, in the input.
By the way, scanf() itself is considered problematic: Why does everyone say not to use scanf? What should I use instead?

Related

Why is the C loop executing one more time than required? [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Closed 4 years ago.
I mistakenly used scanf("%d\n",&val); in one of my programmes, I could not understand the behavior, the function showed.
int main(){
int val;
scanf("%d\n", &val);
printf("%d\n", val);
return 0;
}
Now the program required 2 integer inputs, and prints the first input that was entered.
What difference should that extra \n brings?
I tried to search but couldn't find the answer, even through manual of scanf.
An '\n' - or any whitespace character - in the format string consumes an entire (possibly empty) sequence of whitespace characters in the input. So the scanf only returns when it encounters the next non-whitespace character, or the end of the input stream (e.g. when the input is redirected from a file and its end is reached, or after you closed stdin with Ctrl-D).
From man scanf in my Linux box:
A directive is one of the following:
A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). This directive matches any amount of white space, including none, in the input.
BTW, %d is also a directive.
So your "%d\n" has two directives, the first one reads the number and the second one... well reads any amount of white space, including your end-of-lines. You have to type any non-white space character to make it stop.

why do compiler ask to print two numbers in new line while given newline in arrays? [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Closed 4 years ago.
I mistakenly used scanf("%d\n",&val); in one of my programmes, I could not understand the behavior, the function showed.
int main(){
int val;
scanf("%d\n", &val);
printf("%d\n", val);
return 0;
}
Now the program required 2 integer inputs, and prints the first input that was entered.
What difference should that extra \n brings?
I tried to search but couldn't find the answer, even through manual of scanf.
An '\n' - or any whitespace character - in the format string consumes an entire (possibly empty) sequence of whitespace characters in the input. So the scanf only returns when it encounters the next non-whitespace character, or the end of the input stream (e.g. when the input is redirected from a file and its end is reached, or after you closed stdin with Ctrl-D).
From man scanf in my Linux box:
A directive is one of the following:
A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). This directive matches any amount of white space, including none, in the input.
BTW, %d is also a directive.
So your "%d\n" has two directives, the first one reads the number and the second one... well reads any amount of white space, including your end-of-lines. You have to type any non-white space character to make it stop.

error with scanf and array [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Closed 4 years ago.
I mistakenly used scanf("%d\n",&val); in one of my programmes, I could not understand the behavior, the function showed.
int main(){
int val;
scanf("%d\n", &val);
printf("%d\n", val);
return 0;
}
Now the program required 2 integer inputs, and prints the first input that was entered.
What difference should that extra \n brings?
I tried to search but couldn't find the answer, even through manual of scanf.
An '\n' - or any whitespace character - in the format string consumes an entire (possibly empty) sequence of whitespace characters in the input. So the scanf only returns when it encounters the next non-whitespace character, or the end of the input stream (e.g. when the input is redirected from a file and its end is reached, or after you closed stdin with Ctrl-D).
From man scanf in my Linux box:
A directive is one of the following:
A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). This directive matches any amount of white space, including none, in the input.
BTW, %d is also a directive.
So your "%d\n" has two directives, the first one reads the number and the second one... well reads any amount of white space, including your end-of-lines. You have to type any non-white space character to make it stop.

scanf() behaviour for strings with more than one word

Well I've been programming in C for quite a while now, and there is this question about the function scanf()
here is my problem:
I know that every element in ASCII table is a character and I even know that %s is a data specified for a string which is a collection of characters
My questions:
1.why does scanf() stops scanning after we press enter. If enter is also character why cant it be added as a component of the string that is being scanned.
2.My second question and what I require the most is why does it stops scanning after a space, when space is again a character?
Note: My question is not about how to avoid these but how does this happen
I'd be happy if this is already addressed, I'd gladly delete my question and even if I've presumed something wrong please let me know
"why does scanf() stops scanning after we press enter." is not always true.
The "%s" directs scanf() as follows
char buffer[100];
scanf("%s", buffer);
Scan and consume all white-space including '\n' generated from multiple Enters. This data is not saved.
Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier C11dr §7.21.6.2 8
Scan and save all non-white-space characters. Continue doing so until a white-space is encountered.
Matches a sequence of non-white-space characters §7.21.6.2 12
This white-space is put back into stdin for the next input function. (OP's 2nd question)
A null character is appended to buffer.
Operations may stop short if EOF occurs.
If too much data is save in buffer, it is UB.
If some non-white-space data is saved, return 1. If EOF encountered, return EOF.
Note: stdin is usually line buffered, so no keyboard data is given to stdin until a '\n' occurs.
From my reading of your question, both of your numbered questions are the same:
Why does scanf with a format specifier of %s stop reading after encountering a space or newline.
And the answer to both of your questions is: Because that is what scanf with the %s format specifier is documented to do.
From the documentation:
%s Matches a sequence of bytes that are not white-space characters.
A space and a newline character (generated by the enter key) are white-space characters.
I made miniprogram with scanf for get multiple name without stop on space or ever enter.
i use while
Scanf("%s",text);
While (1)
{
Scanf("%s",text1)
If (text1=='.'){break;}
//here i simple add text1 to text
}
This way i get one line if use the .
Now i use
scanf("%[^\n]",text);
It work great.

what is the purpose of putting a space in scanf like this scanf(" %c",&ch) in place of scanf("%c",&ch)? [duplicate]

This question already has answers here:
What does space in scanf mean? [duplicate]
(6 answers)
Closed 7 years ago.
what is the purpose of putting a space in scanf like this
scanf(" %c",&ch)
in place of
scanf("%c",&ch)?
Also what is input buffer in fflush(stdin)?
Because the space before %c ignores all whitespace. *scanf family of functions ignore all whitespace before any % by default except for %c, %[ and %n. This is mentioned in C11 at:
7.21.6.2.8
Input white-space characters (as specified by the isspace function) are skipped, unless
the specification includes a [, c, or n specifier.
To be complete, here's the part that says all whitespace will be ignored:
7.21.6.2.5
A directive composed of white-space character(s) is executed by reading input up to the
first non-white-space character (which remains unread), or until no more characters can
be read. The directive never fails.
Regarding your second question, fflush(stdin) causes undefined behavior and must not be used (emphasis mine):
7.21.5.2.2
If stream points to an output stream or an update stream in which the most recent
operation was not input, the fflush function causes any unwritten data for that stream
to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
what is the purpose of putting a space in scanf like this scanf(" %c",&ch) in place of scanf("%c",&ch)?
So that scanf would ignore all spaces before the first non-space character is encountered in the stream.
Also what is input buffer in fflush(stdin)?
What you input into the console will exist in the stdin stream.
Don't flush that stream however, it's undefined behavior.
If you want to discard characters entered after scanf is called, you can read and discard them.
The space in the scanf in this case tells scanf to ignore any leading whitespace characters in front of the character you read. Still even if there is no whitespace in front of the character the code will work and read the character successfully.
I am not sure what you are asking in your last question, but stdin is the standard input stream for you program.
scanf(" %c",&ch);
As per the man page,
White space (such as blanks,
tabs, or newlines) in the format string match any amount of white space,
including none, in the input.
Stdin is standard input.The user enters the data for the program, this is first stored in a buffer and then when the program requests data transfers by use of the read operation the data is made available to the program. (using scanf etc).
I had the same problem a while ago in which if I would try to read a variable using scanf ("%c", &ans); it would not read anything. Thus I figured out that the \n character from the last input was being read.
Thus, doing scanf (" %c", &ans); solved my problem.
Although, I could not understand your second question clearly.
Just to give a space from the last object, if not, for example a string, everything will be together with no spaces between them.

Resources