Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to understand - reading characters from files in C

I have just started learning file handling in C, and wondered if I could perform mathematical calculations by reading input from a file, here is the code for just reading the characters and displaying on the console :

int main(void)
{
    FILE *p;
    char a, b, c, ch;

    p = fopen("numbers.txt", "a+");

    while((ch = getc(p)) != EOF)
    {
        fscanf(p, "%c %c %c\n", &a, &b, &c);
        printf("%c %c %c\n", a, b, c);
    }
    fclose(p);

    return 0;
} 

numbers.txt contains (with a space before each character) :

 2 + 3
 5 + 6
 6 + 7

output obtained is :

2 + 3
  + 6
  + 7

I am unable to understand why first line output is as expected but second and third line have missing character, even though new line is given after each expression in numbers.txt.

like image 390
CaptainDaVinci Avatar asked Dec 14 '22 01:12

CaptainDaVinci


2 Answers

An additional character is being scanned at the beginning of each iteration of your while loop

while((ch = getc(p)) != EOF)

Try making the fscanf() statement as the condition for your while loop and check for its return value. According to cplusplus.com:

On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.

If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof or ferror). And, if either happens before any data could be successfully read, EOF is returned.

So try changing your while condition to anyone of the following:

while (fscanf(p, " %c %c %c", &a, &b, &c) != EOF)

or

while (fscanf(p, " %c %c %c", &a, &b, &c) == 3)
like image 101
Cherubim Avatar answered Jan 10 '23 06:01

Cherubim


Using whitespace in the scanf format specifier, like you do with \n, matches any amount of whitespace. The \n and the leading space on the next line are consumed, causing getc to remove the first digit instead of the leading space.

I’d skip getc entirely, as @BLUEPIXY suggested:

while (fscanf(p, " %c %c %c", &a, &b, &c) == 3) {
    printf("%c %c %c\n", a, b, c);
}
like image 38
Ry- Avatar answered Jan 10 '23 06:01

Ry-