Thread: File I/O Merging Files Program

  1. #1
    Registered User
    Join Date
    Nov 2013
    Posts
    33

    File I/O Merging Files Program

    Hi all this is my first post so forgive me if it's incorrectly posted and let me know what I can improve upon in further posts.

    My assignment is to:

    Write a program that merges the numbers in two files and writes the results to a third file. The program reads input from two different files and writes the output to a third file. Both files contain integers in ascending order(smallest to largest). After the program is executed, the output file contains the numbers from the two input files in one longer list, also in ascending order.

    Question:
    I've searched online and I think my function is correct, but I'm confused on how to call output is it "w" for writing or "w+" for reading and writing to the screen to check that the numbers have been merged correctly? Also, how do I display the output file of my function on screen?

    PHP Code:
    #include  <stdio.h>
    #include <stdlib.h>


    void file_merger(FILE *input_1FILE *input_2FILE *output);
    int main (int argcchar argv[])
    {
        
    FILE *input_1, *input_2, *output;
        
    input_1 fopen("numbers1.txt""r");
        
    input_2 fopen("numbers2.txt""r");
        
    output fopen("output.txt""w+");


        if(
    input_1 == NULL || input_2 == NULL)
        {
            
    fprintf(stderr"File failed to open.\n");
            exit(
    1);
         }


        
    fclose(input_1);
        
    fclose(input_2);
        
    fclose(output);
        return 
    0;
    }
    void file_merger(FILE *input_1FILE *input_2FILE *output)
    {
        
    int i1i2value1value2;
        
    i1 fscanf(input_1"%d", &value1);
        
    i2 fscanf(input_2"%d", &value2);


        while(
    i1 == || i2 == 1)
        {
            if(
    value1 <= value2)
            {
                
    fprintf(output"%d\n"value1);
                
    i1 fscanf(input_1"%d", &value1);
            }


            if(
    value2 <= value1)
            {
                
    fprintf(output"%d\n"value2);
                
    i2 fscanf(input_2"%d", &value2);
            }


            while(
    i1 == 1)
            {
                
    fprintf(output"%d\n"value1);
                
    i1 fscanf(input_1"%d", &value1);
            }
            while(
    i2 == 1)
            {
                
    fprintf(output"%d\n"value2);
                
    i2 fscanf(input_2"%d", &value2);
            }
        }

    Last edited by whiteboyfly; 11-28-2013 at 09:50 PM.

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Excellent post!


    Personally, I'd open the file with "w" and then, if you really need to print it out, close it and reopen it with "r". Of course, if you simply need to check the output file for correctness, you could open it in a text editor.


    Your merge logic is not quite right. You need to move the second and third white loops AFTER the initial while loop. The idea is that the initial loop keeps going as long as BOTH files have data. The other two loops are for emptying out whichever file still has data remaining. So your condition on the first while loop should be an &&, not an ||.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Merging two sorted files of integers is easy - first thing is don't over-think it (and you appear to know that).

    There are three states for merging open files:

    file1N >= file2N

    file2N > file1N

    file1 has no more data - run out file2, all remaining N. No comparisons needed.

    or

    file2 has no more data - run out file1, all remaining N. No comparisons needed.

    So basically, you're looking at three while() loops.

    1) While both files have data

    Now one file is empty, but you don't know which one, and you don't care.

    2) While file1 has N, write it out

    3) While file2 has N, write it out

    Either 2 or 3 loop will run, but never both of them.

    In the #1 while loop,
    Code:
    get your N1 and your N2 from your files
    
    do {
       make your comparison. 
    
       if(N1 <= N2) {
          write out N1
          ok1 = fscan in from file1, another N1
       }else {
          write out N2
          ok2 = fscan in from file2, another N2
       }
    
    }while(ok1 > 0 && ok2 > 0);
    
    while #2, 
    
    
    while #3
    You want to use "w+r" mode. You don't need to mix writing with reading, however. Because of the drive and OS buffering, it's easy to goof it up. First, you ONLY write. Then rewind(), then read and print it out onto the screen for you.

    Try the above, I haven't run it, and I'm zapped, but it's close.

    For posting, it's best to use plain text. The forum has it's own nice display for code (including colors and line numbers, and font, etc.). Your formatting interferes with that nice display.

  4. #4
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    You're also checking that your input files are opened (good) but not your output file.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by Adak View Post
    You want to use "w+r" mode.
    Sadly there is no "w+r" mode.
    You mean "w+".

    However, I still prefer my idea.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Registered User
    Join Date
    Nov 2013
    Posts
    33

    Post

    Quote Originally Posted by oogabooga View Post
    Excellent post!


    Personally, I'd open the file with "w" and then, if you really need to print it out, close it and reopen it with "r". Of course, if you simply need to check the output file for correctness, you could open it in a text editor.


    Your merge logic is not quite right. You need to move the second and third white loops AFTER the initial while loop. The idea is that the initial loop keeps going as long as BOTH files have data. The other two loops are for emptying out whichever file still has data remaining. So your condition on the first while loop should be an &&, not an ||.
    Thank you for your help your post has given me two more questions.
    1. Is the code below the correct way to call this function because when I opened the output file it read all of the first list and then all of the second list?
    2. If I'm on a linux cluster that my school has setup could I run my program and then check to see if I have the right output by opening the output.txt file in an editor such as vi?
    Code:
    int main (int argc, char * argv[])
    {
        FILE *input_1, *input_2, *output;
        input_1 = fopen("numbers1.txt", "r");
        input_2 = fopen("numbers2.txt", "r");
        output = fopen("output.txt", "w+");
    
    
        if(input_1 == NULL || input_2 == NULL)
        {
            fprintf(stderr, "File failed to open.\n");
            exit(1);
         }
        
        file_merger(input_1, input_2, output);
    
        fclose(input_1);
        fclose(input_2);
        fclose(output);
        return 0;
    }
    Last edited by whiteboyfly; 11-28-2013 at 11:49 PM.

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    I don't see a call to the function in main.

    You seem to be missing
    Code:
        file_merger(input_1, input_2, output);

    And, yes, you could look at it in vi.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  8. #8
    Registered User
    Join Date
    Nov 2013
    Posts
    33
    Sorry i just noticed it thank you for all your help.

  9. #9
    Registered User
    Join Date
    Nov 2013
    Posts
    33
    Hopefully this is my last question on this program. Every time I check my output file I see file1 in ascending order and then file2 in ascending order, when it should be, as the name entails, one list of file1 and file2 together in ascending order. Is this from a previous run of my code because I think the function is correct.
    Here is my function
    Code:
    void file_merger(FILE *input_1, FILE *input_2, FILE *output)
    {
        int i1, i2, value1, value2;
        i1 = fscanf(input_1, "%d", &value1);
        i2 = fscanf(input_2, "%d", &value2);
    
    
        while(i1 == 1 && i2 == 1)
        {
            if(input_1 <= input_2)
            {
                    fprintf(output, "%d\n", value1);
                    i1 = fscanf(input_1, "%d", &value1);
            }
            else
            {
                    fprintf(output, "%d\n", value2);
                    i2 = fscanf(input_2, "%d", &value2);
            }
            }
            while(i1 == 1)
            {
                fprintf(output, "%d\n", value1);
                i1 = fscanf(input_1, "%d", &value1);
            }
            while(i2 == 1)
            {
                fprintf(output, "%d\n", value2);
                i2 = fscanf(input_2, "%d", &value2);
            }
    }

  10. #10
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You haven't yet moved the second and third while loops outside of the first one. Re-read Adak's post which (as usual) is clearer than mine.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  11. #11
    Registered User
    Join Date
    Nov 2013
    Posts
    33
    This is probably my mistake, but I'd like to learn this. I was under the impression that my first while loop exists on line 20, which was poorly formatted above. Otherwise I am missing this concept.
    Code:
    void file_merger(FILE *input_1, FILE *input_2, FILE *output) { int i1, i2, value1, value2; i1 = fscanf(input_1, "%d", &value1); i2 = fscanf(input_2, "%d", &value2); while(i1 == 1 && i2 == 1) { if(input_1 <= input_2) { fprintf(output, "%d\n", value1); i1 = fscanf(input_1, "%d", &value1); } else { fprintf(output, "%d\n", value2); i2 = fscanf(input_2, "%d", &value2); } } while(i1 == 1) { fprintf(output, "%d\n", value1); i1 = fscanf(input_1, "%d", &value1); } while(i2 == 1) { fprintf(output, "%d\n", value2); i2 = fscanf(input_2, "%d", &value2); } }

  12. #12
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Oh, sorry, I missed that brace.

    But your problem is that you've accidentally changed from comparing the values to comparing the file pointers! I.e., this
    Code:
    if(input_1 <= input_2)
    should be this
    Code:
    if(value1 <= value2)
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  13. #13
    Registered User
    Join Date
    Nov 2013
    Posts
    33
    I can't believe I missed that. I know I'm sounding like a broken record, but I can't thank you enough for your help, oogabooga. Also, thank you to everyone else who contributed to this post. The program is running as it should and my understanding of file i/o has been expanded.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with merging two files
    By cloudstrife910 in forum C++ Programming
    Replies: 2
    Last Post: 10-06-2010, 12:09 PM
  2. Merging files (*.001, *.002 etc.)
    By Altertwin in forum Windows Programming
    Replies: 4
    Last Post: 07-11-2010, 01:24 PM
  3. merging files into one
    By mbooka in forum C Programming
    Replies: 6
    Last Post: 02-16-2006, 07:31 PM
  4. Merging files....
    By girlzone in forum C++ Programming
    Replies: 3
    Last Post: 05-10-2003, 02:39 PM
  5. Merging Files
    By Natase in forum C Programming
    Replies: 6
    Last Post: 09-25-2001, 07:10 PM