Merging Files

This is a discussion on Merging Files within the C Programming forums, part of the General Programming Boards category; I have a program that splits a large, unsorted, file into two smaller files, sorts the two files, then merges ...

  1. #1
    Registered User Natase's Avatar
    Join Date
    Aug 2001
    Posts
    123

    Merging Files

    I have a program that splits a large, unsorted, file into two smaller files, sorts the two files, then merges them into "final.txt".

    The user is asked to enter a guess as to how many lines exist in the original file. The program works fine except when the user's guess is too small (so small that "file1.txt" contains only 1 or 2 lines of text and "file2.txt" contains the majority). In this case the last line of "file1.txt" is written to "final.txt" twice. Any ideas... I know the problem lies in this function?

    Code:
    void merge_files(void) {
       char temp1[80], temp2[80];
       int comparison;
       FILE *input1, *input2, *output;
       input1=fopen("file1.txt", "r");
       input2=fopen("file2.txt", "r");
       output=fopen("final.txt", "w");
       fgets(temp1, 80, input1);
       fgets(temp2, 80, input2);
       while (!feof(input1) && !feof(input2)) {
          comparison=strcmp(temp1, temp2);
          if (comparison<0) {
             fprintf(output, "%s", temp1);
             fgets(temp1, 80, input1);
          } else {
             fprintf(output, "%s", temp2);
             fgets(temp2, 80, input2);
          }
       }
       while (!feof(input1)) {
          fprintf(output, "%s", temp1);
          fgets(temp1, 80, input1);
       }
       while (!feof(input2)) {
          fprintf(output, "%s", temp1);
          fgets(temp1, 80, input2);
       }
       fclose(input1);
       fclose(input2);
       fclose(output);
    }
    Cheers...

  2. #2
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    Salem mentions this problem almost everyday....

    Dont bother with calls to feof() but instead explicitly check for EOF
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  3. #3
    Registered User Natase's Avatar
    Join Date
    Aug 2001
    Posts
    123
    Salem mentions this problem almost everyday....
    I was talking with Salem about this very code in a thread a while back. It's taken me this long to find out there actually was a problem with it (the case where the user wildly underestimates the number of lines of text in his file).

    Dont bother with calls to feof() but instead explicitly check for EOF
    Firstly: I don't know how to do that (maybe fgets returns EOF?)

    Secondly: How would I change the above loop so that it quits when one of the files returns EOF, but continues reading from the other?

    Thanks...

  4. #4
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  5. #5
    Registered User Natase's Avatar
    Join Date
    Aug 2001
    Posts
    123
    A better way is to remove the feof call altogether, and go with
    Code:
    int ch;
    while ( (ch=fgetc(fp)) != EOF ) {
      // do stuff
    }
    Thanks... but does fgets also return a value (and does this also have to be an int?)?

    ie will this work for strings

    Code:
    int x1, x2;
    while ( x1=fgets(temp1, 80, input1) != EOF && x2=fgets(temp2, 80, input2) != EOF) {}

  6. #6
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,535
    > ie will this work for strings
    No (well not quite)
    fgets returns NULL at EOF

    Code:
    int main ( ) {
        FILE *input1, *input2, *output;
        char temp1[80],temp2[80];
        char *f1, *f2;
        f1 = fgets( temp1, sizeof(temp1), input1 ); // get the first two lines
        f2 = fgets( temp2, sizeof(temp2), input2 );
        while ( f1 && f2 ) {    // only while not at either end of file
          int comparison=strcmp(temp1, temp2);
          if (comparison<0) {
             fputs( temp1, output );
             f1 = fgets( temp1, sizeof(temp1), input1 );
          } else {
             fputs( temp2, output );
             f2 = fgets( temp2, sizeof(temp2), input2 );
          }
        }
        // at the end of one file, copy the remainder of the other file
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  7. #7
    Registered User Natase's Avatar
    Join Date
    Aug 2001
    Posts
    123
    Ahhhh... that's brilliant... thanks for that...

    So, what I have learned today is:

    fgetc() returns an integer EOF (-1 as far as I can see)

    fgets() returns a NULL character pointer

    fgets() doesn't empty the buffer it created after reading the string


    At least I hope so...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Error opening files in a different dir
    By Ozzie in forum C++ Programming
    Replies: 3
    Last Post: 10-09-2008, 06:55 AM
  2. Working with muliple source files
    By Swarvy in forum C++ Programming
    Replies: 1
    Last Post: 10-02-2008, 08:36 AM
  3. Multiple Cpp Files
    By w4ck0z in forum C++ Programming
    Replies: 5
    Last Post: 11-14-2005, 01:41 PM
  4. Folding@Home Cboard team?
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 398
    Last Post: 10-11-2005, 08:44 AM
  5. Batch file programming
    By year2038bug in forum Tech Board
    Replies: 10
    Last Post: 09-05-2005, 03:30 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21