Old Wolf said:
My original post was not concerned with error-checking. But if you
are to check for EOF then I think it is still much simpler in the
fscanf situation! The code with error-checking would have to be
something like:
int ch;
/* ... */
ch = fgetc(fp);
if ( ch == EOF )
break; /* or whatever */
two_bytes[count++] = ch;
if ( fscanf(fp, "%c", &two_bytes[count++]) )
break;
Furthermore, the first snippet still has the problem of out-of-range
assignment, which I don't see an easy way around.
Where do you see the possibility of an out of range assignment in
the first snippet? Unless two_bytes is defined as {signed} char --
but my commentary specifically said to define it as unsigned.
fgetc() will output EOF or an "unsigned char converted to int", so
unless your unsigned char has the same range as 0 to INT_MAX
you are going to be able to fit the converted value. But since unsigned
char may not have padding bits and int must have the signed range
available to it, int would have to be have a type larger than
0 to UCHAR_MAX, and we'd be getting into pathological cases
where sizeof(int) > 1 but all the int bits (except the sign bit)
beyond those needed to hold UCHAR_MAX would have to be padding.
Maybe possible, but we're talking DS9K environments now.
if ( fscanf(fp, "%c", &two_bytes[count++]) )
break;
If fscanf() successfully reads a char in that snippet, then
it is going to return the number of input items successfully
matched, namely 1, so the if condition would be true.
If fscanf() encounters EOF then it is going to return EOF
which is guaranteed negative (and hence non-zero), and the
logical value of any negative number is true, so the if
condition would be true.
If the format item were nearly anything other than %c then
if characters were present but failed to match the format
spec then 0 items would be matched and the return value would
be 0 and the if condition there would be false. But %c cannot
fail to match a character if one is present, so that's not
going to happen.
Hence it would appear that you got the termination condition
on the fscanf() case wrong, which argues against your earlier
claim that it is easier to get the termination condition
right for fscanf() than for fgetc().