0

im trying to learn c/c++ and I was creating a 'append' function, it will append the 'inFile' text to the 'outFile', creating 'outFile' if it doesnt exist.

  int AppendFile(const char * inFIle, const char * outFile)
  {
     FILE * ptrInputFile = fopen(inFIle, "rb");                      /*Open first file*/
     if (ptrInputFile == NULL)
     {
        fprintf(stderr, "Error opening \"%s\"", inFIle);            /*Output to cerr*/
        return -1;
     }

     FILE * ptrOutputFile = fopen(outFile, "ab");                    /*Open second file*/
     if (ptrOutputFile == NULL)
     {
        fclose(ptrInputFile);                                       /*Close inFile that was openned in lines above*/
        fprintf(stderr, "Error opening \"%s\"", outFile);           /*Output to cerr*/
        return -1;
     }

     /*read char by char and append.*/
     while (1)
     {
        char tempChar = fgetc(ptrInputFile);                        /*Read char in stream*/
        if (feof(ptrInputFile))                                     /*Check if EOL if so, break*/
        {
           break;
        }
        fprintf(ptrOutputFile, "%c", tempChar);                     /*Send character to output stream*/
     }

     /*Close files.*/
     fclose(ptrInputFile);
     fclose(ptrOutputFile);

     return 0;                                                      /*Return successfully*/
  }

Code above works, but my first iteration was:

  /*read char by char and append.*/
     while (1)
     {
        if (feof(ptrInputFile))                                     /*Check if EOL if so, break*/
        {
           break;
        }
        char tempChar = fgetc(ptrInputFile);                        /*Read char in stream*/
        fprintf(ptrOutputFile, "%c", tempChar);                     /*Send character to output stream*/
     }

but having the fget in there puts a 0xFF between both files, how can it be? to my understanding 'feof' sniffs the current caracter in the strean to check for EOF, and 'fget' returns the character and advances the pointer, right? so my logic was, check first for and EOF so you dont write the EOF to the stream, but the result was a 0xFF in the stream, how can it be?

to my logic the following code will do:

     while (1)
     {
        char tempChar = fgetc(ptrInputFile);                        /*Read char in stream*/
        if (feof(ptrInputFile))                                     /*Check if EOL if so, break*/
        {
           break;
        }
        fprintf(ptrOutputFile, "%c", tempChar);                     /*Send character to output stream*/
     }

get the char and then sniff and then write it, so at the last character, it will read it and sniff the EOL and exit so the last character will be lost, how can it be that I'm not loosing any characters?

Thank you for your help.

PS. I know i can use the fstream classes for c++ but the lesson im taking is on fopen, fclose and fprint so I had to use those.

EDIT: To me is counter intuitive the way the algorith works, so maybe Im not seeing something, for example, having the code:

 while (1)
 {
    if (feof(ptrInputFile))
    {
       break;
    }
    char tempChar = fgetc(ptrInputFile);
    fprintf(ptrOutputFile, "%c", tempChar);
 } 

The file contains 'H','EOF', 'ptrInputFile' will point to 'H', while iterations are as follows: 1. H is EOF? No, continue, copy 'H' to tempChar and advance pointer (fgetc does this), write to ptrOutputFile the 'H. 2. 'ptrInputFile' now points to 'EOF, 'EOF' is EOF, yes break.

For some reason this code is writing me an extra character, a 0xFF.

The code that works fine is:

 while (1)
 {
    char tempChar = fgetc(ptrInputFile);
    if (feof(ptrInputFile))
    {
       break;
    }
    fprintf(ptrOutputFile, "%c", tempChar);
 } 

like the example above, file contains 'H','EOF', ptrInputFile points to 'H', iterations are as follows (at least what I understand): 1. copy 'H' to tempchar and advance the pointer 1, now ptrInputFile points to EOF, is ptrInputFile EOF? yes, ok break.

So to me it should never write anything but it does, my question is on how exactly feof and fgetc works.

user2982010
  • 77
  • 3
  • 9
  • 1
    Possible duplicate of [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – O'Neil Jan 21 '18 at 05:01

1 Answers1

2

This is a variant of Why is “while ( !feof (file) )” always wrong? The test for EOF is done before the read that might find EOF, so the eof is used.

An if statement that exits the loop immediately after a while is no different from putting the if's condition inside the while loop.

 while (1)
 {
    if (feof(ptrInputFile)) //Check if we SAW eof. This checks before the read
    {
       break;
    }
    char tempChar = fgetc(ptrInputFile); // read may well be EOF, but you don't check.
    fprintf(ptrOutputFile, "%c", tempChar); // and wind out printing the EOF. Oops
 }

is identical to

 while (feof(ptrInputFile)) //Check if we SAW eof. This checks before the read
 {
    char tempChar = fgetc(ptrInputFile); // read may well be EOF, but you don't check.
    fprintf(ptrOutputFile, "%c", tempChar); // and wind out printing the EOF. Oops
 }

What you want looks more like

int tempChar; // note int, not char. fgetc returns an int to make sure EOF is out
              // of char range
while ((tempChar = fgetc(ptrInputFile)) != EOF) //read then test if we read  EOF
{
    fprintf(ptrOutputFile, "%c", (char)tempChar); // print known-good character
}
user4581301
  • 33,082
  • 7
  • 33
  • 54