Check the return value from fscanf()
more carefully; it will return, for example, 3 if it matches 3 fields. You might want to be careful about the sizes of the various strings to avoid buffer overflows - that is, however, probably a subject for another day.
The possibility which strikes me is that the last tab in the format string might be better as a newline - but fscanf()
normally takes a fairly liberal attitude towards white space in the format strings and data.
This simplified (but complete, working) version of your code behaves more or less sanely on MacOS X.
#include <stdio.h>
int main(void)
{
char b1[20], b2[20], b3[20], b4[20], b5[20];
while (fscanf(stdin,"%s\t%s\t%s\t%s\t%s\t", b1, b2, b3, b4, b5) == 5)
printf("%s\t%s\t%s\t%s\t%s\n", b1, b2, b3, b4, b5);
return 0;
}
However, it did treat a string 'k k k k k
' (5 single letters separated by blanks) as equivalent to separated by 5 tabs. The problem, therefore, is that section §7.19.6.2 of the C standard specifies:
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.
Input white-space characters (as specified by the isspace function) are skipped, unless
the specification includes a [, c, or n specifier.
Also, with regards to the '%s' specifier, it says:
Matches a sequence of non-white-space characters.
To force matching of actual tabs, you'd have to work quite a bit harder. It would be much easier to resort to the 'read a line into a buffer (fgets()
) and split it manually'. This will also allow you to enforce 5 words on a line and you can generate an error or warning if there are too few or too many fields. With fscanf()
, you cannot do that. If you type 8 words on a line, it will read the first five the first time, then the remaining three words on the line plus the first two on the next, and so on.