Can someone explain how does this work? I know that it reads a string(with spaces), but I don't really understand the mechanism behind. Can someone explain it to me piece by piece?
scanf("%[^\n]%*c",string);
Can someone explain how does this work? I know that it reads a string(with spaces), but I don't really understand the mechanism behind. Can someone explain it to me piece by piece?
scanf("%[^\n]%*c",string);
scanf("%[^\n]%*c",string);
This says "read everything until a newline character and then read one character". *
(in %*c
) is to suppresses the assignment. That's it reads a line and consumes the newline character.
From scanf()
:
An optional '*' assignment-suppression character: scanf() reads input as directed by the conversion specification, but discards the input. No corresponding pointer argument is required, and this specification is not included in the count of successful assignments returned by scanf().
But I'd, for reading lines, use fgets()
instead and consume the trailing newline afterwards.
char string[256];
if (fgets(string, sizeof string, stdin) == NULL) {
/* handle failure */
}
string[strcspn(string, "\n")] = 0; /* For removing the newline if present */
which is less error prone and better to understand.
If you are using glibc, you can use getline()
as well.
From the man page:
All conversions are introduced by the % (percent sign) character
A conversion is how we match certain text strings. For example a %s
matches a string, and %d
matches a decimal integer. So looking at your string, we have a "%[
conversion, which according to the man page:
[ Matches a nonempty sequence of characters from the specified set of accepted characters; ... the set is defined by the characters between the open bracket [ character and a close bracket ] character.
So this conversion is going to define a list of characters which will be matched and read into your string. Important to this is:
The set excludes those characters if the first character after the open bracket is a circumflex ^.
And if you look at your string "%[^\n]%*c"
you've got %[^\n]
which means that you're matching any character until you hit a newline character.
Next, you have a %*
the star is a conversion which ignores what matches after it. From the man page:
Suppresses assignment. The conversion that follows occurs as usual, but no pointer is used; the result of the conversion is simply discarded.
So if you look at your last match, you've got a c
,
c Matches a sequence of width count characters (default 1);
so the %*c
means that you're going to match 1 character, and then discard it (the character being matched is the newline - which the %[^\n]
didn't consume because you matched everything up to that newline), it won't be stored in your string
variable.
Reading the man page is your friend. I hope this helps.