I am trying to read file with 30 rows and 5 columns with separator of “tab”. Each time I get only part of the rows.
In the windows environment it’s working good. Any idea why in unix it is not working?
while (fscanf(FFMapFile, "%s\t%s\t%s\t%s\t%s\t", fnfMap[i].COS_ID, fnfMap[i].FF_First_Act, fnfMap[i].FF_Next_Act, nfMap[i].Free_FF_allowed, fnfMap[i].FF_Change_Charge) != EOF)
{
sprintf(s,"%s\t%s\t%s\t%s\t%s\t", nfMap[i].COS_ID, fnfMap[i].FF_First_Act, fnfMap[i].FF_Next_Act, fnfMap[i].Free_FF_allowed, fnfMap[i].FF_Change_Charge);
error_log(s,ERROR);
i++; }
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.
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:Also, with regards to the ‘%s’ specifier, it says:
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. Withfscanf(), 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.