Reputation: 65
pls can you explain why example1 is not working and example2 works? Or explain how can I put character with whitespace to string used in struct? I am beginner at programming C, in other problems I was able to find solution but in this case I do not really know :(
example1 (there not working whitespace string):
#include <stdio.h>
struct string {
char word[20];
char sentence[100];
} s;
int main() {
printf("Enter word:\t");
scanf("%s", s.word); //1st input without whitespace
printf("\nEnter more words with whitespace:\t");
scanf("%[^\n]s", s.sentence); //2nd input with whitespace - not working
printf("\nWord is: %s", s.word); // 1st input printed (OK)
printf("\nSentence is: %s \n", s.sentence); // 2nd input not printed (NOT! OK)
return 0;
}
example2 (working whitespace string):
#include <stdio.h>
struct string {
char word[20];
char sentence[100];
} s;
int main() {
printf("\nEnter more words with whitespace:\t");
scanf("%[^\n]s", s.sentence); //1st input with whitespace
printf("Enter word:\t");
scanf("%s", s.word); //2nd input without whitespace
printf("\nWord is: %s", s.word); // 2nd input printed (OK)
printf("\nSentence is: %s \n", s.sentence); // 1st input printed (OK)
return 0;
}
Between "example1" and "example2" are different order of input (see at code comment). I dont know how can I use whitespace to scanf input in struct. And sorry for my english.
Thank you in advance!
Upvotes: 1
Views: 1522
Reputation: 882028
For a start, the correct specifier for anything other than a newline is %[^\n]
rather than %[^\n]s
. Yours works but only as a coincidence of the values chosen :-)
Calling scanf
with the %s
format specifier will stop scanning when it reaches white space, that's how it works. From C11 7.21.6.2 /12
, where it talks about the conversion specifiers and their meanings
s - Matches a sequence of non-white-space characters.
The reason why you're getting a blank sentence in the first code sample has to do with the way the word is scanned. In scanning the word, it stops at the first white space and leaves that in the input buffer. That first white space is the newline at the end of your word.
That means the sentence scan will grab everything up to the next newline which, because the newline is the first thing in the buffer, means it will get an empty string.
You can fix this by placing a getchar()
after the word scan to consume the newline, before attempting to read the sentence.
However, if you really want robust user input in C, you'll be better off building something around fgets
, something like the code found here.
The reason it works when you swap them around has to do with this snippet in that same standard (7.21.6.2 /8
) which details what happens before the item is scanned:
Input white-space characters (as specified by the
isspace
function) are skipped, unless the specification includes a[
,c
, orn
specifier.
So, even though the word scan in your second example also starts with a newline in the buffer, the %s
specifier skips it before attempting to read a word. That's something the [
specifier does not do, as you've already seen.
Upvotes: 2
Reputation: 170
In your example1, scanf("%s", s.word) would only scan the first word, but would not flush the rest of the line.
This should solve your issue:
#include <stdio.h>
struct string {
char word[20];
char sentence[100];
} s;
int main() {
char c;
printf("Enter word:\t");
scanf("%s", s.word); //1st input without whitespace - if multiple words are entered, only the first word will be taken
while ((c = getchar()) != '\n') {
/* discard */ ;
}
printf("\nEnter more words with whitespace:\t");
scanf("%[^\n]s", s.sentence); //2nd input with whitespace - this should work now
printf("\nWord is: %s", s.word); // 1st input printed (OK, only first word printed)
printf("\nSentence is: %s \n", s.sentence); // 2nd input printed (OK NOW!!!)
return 0;
}
Upvotes: 1