Reputation: 4685
char szA[256]={0};
scanf("%[^a]%s",&szA); //failed when trailing string
scanf("%[^a]|%s",&szA); //worked whatever the input
What does '|' mean in a format string. I cannot find official specification. Is there anyone who can give me some clue?
When I input something with several '|' ,the latter one still works(just means that the program not breakdown). Doesn't it need two buffers given after the format string. The former one crashed when input string can be divided into more than one string. So there is still other difference between them. What is it ?
So, I cannot understand why the latter one works when the buffer number less than directive number while the former one fails. Or can someone give me a input string to make the latter one crash.
Upvotes: 2
Views: 581
Reputation: 4685
So, after some conversation, in my comprehension, the latter one requires the remaining stream starts with '|' when dealing with the '|%s' directive. While the former directive excludes 'a' and leaves the remaining stream starts with 'a'. So the trailing directive always matches nothing and doesn't need to put anything into the buffer. So it never crashes even though the buffer not given.
Upvotes: 0
Reputation: 206567
What does '|' mean in a format string. I cannot find official specification. Is there anyone who can give me some clue?
It means that the code expects a literal |
in the input stream.
Having said, that format specifier is not going to work.
The %[^a]
part will capture all characters that are not a
. That means it will capture even a |
from the input stream. It will stop capturing when the character a
is encountered in the stream. Of course that does not match the literal |
in the format string. Hence, nothing after that will be processed.
If I provide the input def|akdk
to the following program
#include <stdio.h>
int main()
{
char szA[256] = {0};
char temp[100] = {0};
int n = scanf("%[^a]|%s", szA, temp);
printf("%d\n%s\n%s\n", n, szA, temp);
}
I get the following output
1
def|
which makes perfect sense. BTW, the last line in the output is an empty line. I'm not sure how to show that in an answer.
When I change the scanf
line to
int n = scanf("%[^a]a%s", szA, temp);
I get the following output
2
def|
kdk
which makes perfect sense.
Upvotes: 4
Reputation: 881303
It's not one of the format specifiers so it's a literal |
character, meaning it must be present in the input stream. The official specification is the section entitled The fscanf function
found in the ISO standard (e.g., C11 7.21.6.2
) and the relevant section states:
The format is composed of zero or more directives: one or more white-space characters, an ordinary multibyte character (neither % nor a white-space character), or a conversion specification.
A directive that is an ordinary multibyte character is executed by reading the next characters of the stream. If any of those characters differ from the ones composing the directive, the directive fails and the differing and subsequent characters remain unread.
You can see the effect in the following complete program which fails to scan "four|1"
when you're looking for the literal _
but works fine when you're looking for |
.
#include <stdio.h>
int main(void) {
char cjunk[100];
int ijunk;
char inStr[] = "four|1";
if (sscanf(inStr, "%4s_%d", cjunk, &ijunk) != 2)
printf ("Could not scan\n");
if (sscanf(inStr, "%4s|%d", cjunk, &ijunk) == 2)
printf ("Scanned okay\n");
return 0;
}
Upvotes: 2