-2

I'm having trouble understanding the result of this:

    fscanf(FILE,"%s|%s", str1, str2);
    printf("Number:%s, Name:%s", str1, str2);

Content of FILE:

 01234|MY_NAME

Expected Output:

 Number:01234, Name:My_NAME

Output:

 Number:01234|MY_NAME, Name:╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠01234|MY_NAME

Can someone explain why it gives that output?

P/s: I've solved it with this code:

    fscanf(FILE,"%[^|]|%[^|]", str1, str2);
    printf("Number:%s, Name:%s", str1, str2);

But I still don't understand why "%s|%s" gives the previous output.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • 1
    You may find the [documentation for `scanf`](http://en.cppreference.com/w/c/io/fscanf), and particularly the section of format specifiers and how they work, to be helpful. I suspect you need a `[set]` configuration, but you will ultimately confirm that. – WhozCraig Jan 09 '18 at 18:51
  • 1
    This kind of parsing job is better done with `fgets` (or `getline`, if available) and `strtok` (or `strsep`, if available). `scanf` is almost always more trouble than it's worth, even ignoring how`%s` is every bit as dangerous as `gets` and numeric overflow provokes undefined behavior. – zwol Jan 09 '18 at 18:58
  • "I still don't understand why "%s|%s" gives ... Number:01234|MY_NAME, Name:╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠01234|MY_NAME". Is "Number:01234|MY_NAME" confusing? – chux - Reinstate Monica Jan 09 '18 at 20:13
  • Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a [mcve]. – Stargateur Jan 09 '18 at 20:35

1 Answers1

0

The %s directive tells fscanf to skip over any initial whitespace and read 1 or more non-whitespace characters into the argument char *.

01234|MY_NAME is all non-spacey, so it ends up being placed in str1 by the first %s.

Then the | in the format string tells fscanf to read a literal | character. This fails because there is no input left. At this point fscanf gives up and returns 1 to indicate that it successfully filled one of the variables.

However, your program ignores the return value from fscanf, so it doesn't realize what happened. It blindly outputs str1 (containing 01234|MY_NAME) and str2 (which is uninitialized and prints garbage until it happens to find a '\0' in memory).

melpomene
  • 84,125
  • 8
  • 85
  • 148