C scanf with spaces problem [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you allow spaces to be entered using scanf?
printf("please key in book title\n");
scanf("%s",bookname);
i inside the data like this :-
C Programming
but why output the data like this :-
C
lose the Programming (strings) ?
why
thanks.

The %s conversion specifier causes scanf to stop at the first whitespace character. If you need to be able to read whitespace characters, you will either need to use the %[ conversion specifier, such as
scanf("%[^\n]", bookname);
which will read everything up to the next newline character and store it to bookname, although to be safe you should specify the maximum length of bookname in the conversion specifier; e.g. if bookname has room for 30 characters counting the null terminator, you should write
scanf("%29[^\n]", bookname);
Otherwise, you could use fgets():
fgets(bookname, sizeof bookname, stdin);
I prefer the fgets() solution, personally.

Use fgets() instead of scanf()

Well bookname surly is some kind of char ;-)
Point is that scanf in this form stop on the first whitespace character.
You can use a different format string, but in this case, one probably should prefer using fgets.
scanf really should be used for "formatted" input.

Related

Trailing newline when using scanf() to take string input with whitespace [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Closed 28 days ago.
I am getting problem when using scanf() to take int input, then move to take a whole string that also accept whitespace in it. But somehow the scanf() take place first before the printf() even showed up. Still playing around with either scanf() and fgets() for proper solutions
Here is my snippet code
int age; char name_user[35];
printf("age\t: "); scanf("%d\n",&age);
printf("name\t: "); scanf("%[^\n]%*s", name_user);
printf("result\t: %s is %d years old\n",name_user,age);
with the output like this
age : 30
hotpotcookie
name : loremipsum
result : hotpotcookie is 30 years old
are there any workarounds for the input hotpotcookie take place in the name output? so it could be similar like this
age : 30
name : hotpotcookie
result : hotpotcookie is 30 years old
"\n" consumes 0 or more white-spaces until a non-white-space is detected. This means scanf() will not return at the end-of-line as it is looking for white-spaces after a '\n'.
scanf("%d\n",&age); does not return until detecting non-white-space after the numeric input.
Use scanf("%d",&age);.
scanf("%[^\n]%*s", name_user); also risks buffer overflow.
Use a width as in scanf(" %34[^\n]", name_user);
Better code checks the return value from scanf() before using the object(s) hopefully populated by the scan.
Even better code does not use scanf(). Instead use fgets() to read a line of user input into a string and then parse with strotl(), sscanf(), etc.

Wanting scanf to proceed without all parameters filled [duplicate]

This question already has answers here:
How to make that scanf is optionally ignoring one of its conversion specifiers?
(4 answers)
Closed 2 years ago.
I want to have a scanf function that allows the user to input up to four integers separated by spaces but still run if only 2 integers are put in.
scanf("%d %d %d %d", &command, &num_one, &num_two, &num_three);
scanf does exactly that. It returns the number of successful conversions it performed. If it cannot perform a conversion (or cannot match a literal character), it stops reading precisely at that point.
You should always check its return value, even if the examples you are copying don't do that.
What scanf doesn't guarantee is that the values converted are separated by spaces. They might be separated by newlines. If you want a newline character to stop the scan, you need to read the line using something like fgets (or, better if possible, the Posix getline function), and then call sscanf on the line which was read.
You could also force scanf to stop at the end of the line by using %*[ \t] instead of to separate the %ds, which will only match space and tab characters. (The * causes scanf to not try to save the matched string, and also to not count the conversion in its return count.) But that will run you into the other problem with scanf: if there is garbage in the line, you normally want to continue reading with the next line. The getline/sscanf solution will do that for you. If you use scanf, you'll need to manually flush the rest of the input line, which requires calling fgets or getline anyway.
And while I'm at it, note that there is no difference between scanf("%d %d %d %d", ...) and scanf("%d%d%d%d", ...), because %d, like all scanf conversions other than %c, %[ and %%, skips leading whitespace.

Get words which contains space in c [duplicate]

This question already has answers here:
Simple C scanf does not work? [duplicate]
(5 answers)
Closed 7 years ago.
I need to get words from user which contains space as I expressed at title with struct statement.
For example :
#include <stdio.h>
struct knowledge
{
char name[30];
}person;
int main()
{
scanf("%s",person.name);
printf("\n\n%s",person.name);
}
When I run this program and enter a sentence like "sentence" there is no problem. It show me again "sentence".
However, when I enter "sentence aaa" it shows me just first word ("sentence"). What is the matter here? Why it doesn't show me all ("sentence aaa") I entered?
Instead of scanf() use
fgets(person.name,sizeof(person.name),stdin);
It is always a bad idea to use scanf() to read strings. The best option is to use fgets() using which you avoid buffer overflows.
PS: fgets() comes with a newline character
%s format specifier stops scanning on encountering either whitespace or end of stream. hence, you cannot input a "sentence" with space using scanf() and %s.
To scan a "whole line" with space, you need to use fgets(), instead.

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.

scanf(%s) not allowing space? C Programming [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do you allow spaces to be entered using scanf?
char inputStr[64];
int inputInt;
printf("Enter a number:");
scanf("%d",&inputInt);
printf("\nEnter a string:");
scanf("%s",&inputStr);
The above code has 2 part, reading a integer and string.
Reading an integer is fine.
Reading a string also fine considering characters are under 64 and there is no SPACE.
That is the problem.
scanf only reads the character up to a space.
Everything after the space is gone.
How can I include the space also in scanf?
Rather than using scanf("%s", ...), use:
fgets(inputStr, 64, stdin)
It's better practice as it isn't prone to buffer overflow exploits and it will read in a whole line of input, which it seems you're trying to do. Note that the newline character, \n, is also read into the buffer when using fgets (assuming that the whole line manages to fit into the buffer).
Also, when passing an array to a function, as you do with your second scanf call, you don't need to use the address-of operator (&). An array's name (ie. inputStr) is the address of the start of the array.
Use fgets instead (gets is unsafe) if you want to read a line instead.
fgets(inputStr, 64, stdin)
If you want to continue using scanf (e.g., if this string is only some of the input you're reading with scanf), you could consider using a "scanset" conversion, such as:
scanf("%63[^\n]%*c", inputStr);
Unlike fgets, this does not include the trailing new-line in the string after reading. Also note that with a scanset conversion, you specify the maximum length of string to read rather than the buffer size, so you need to specify one smaller than the buffer size to leave space for the terminating NUL.
I've included the "%*c" to read but discard the new-line. A new-line is considered white-space, which is treated specially in a scanf conversion string. A normal character would just match and ignore that character in the input, but white-space matches and ignores all consecutive white-space. This is particularly annoying with interactive input, because it means the white-space conversion won't finish matching until you enter something other that white-space.
Jesus has the answer -- switch to fgets(3); in case you're curious why you cannot capture whitespace with scanf(3):
s Matches a sequence of non-white-space characters; the
next pointer must be a pointer to character array that
is long enough to hold the input sequence and the
terminating null character ('\0'), which is added
automatically. The input string stops at white space
or at the maximum field width, whichever occurs first.

Resources