Ad

How To Merge The Contents Of Two Files Into A New File, Appearing Side By Side By Line?

- 1 answer

I've been trying to merge the contents of two .txt files into a third .txt file that combines the output. All I know how to do (and all I have been able to find answers for), however, is to merge them by putting the contents of the first file first, and the second file second. However, I would prefer the output to list the first line of the first file, then the first line of the second file -- followed on a new line by the second line of the first file and the second line of the second file.

To make this clearer visually, the code is currently appearing as:

file1-line1
file1-line2
file1-line3
file2-line1
file2-line2
file2-line3

... When I'd like it to appear as:

file1-line1 file2-line1
file1-line2 file2-line2
file1-line3 file2-line3

The code I have is very basic and executes the first example fine:

int main() 
{ 
   FILE *pointer1 = fopen("file1.txt", "r"); 
   FILE *pointer2 = fopen("file2.txt", "r"); 
   FILE *pointer3 = fopen("combined.txt", "w"); 
   int ch; 
  
   if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL) 
   { 
         puts("Could not open files"); 
         exit(0); 
   } 
  
   while ((ch = fgetc(pointer1)) != EOF) 
      fputc(ch, pointer3); 
  
   while ((ch = fgetc(pointer2)) != EOF) 
      fputc(ch, pointer3); 
  
   printf("Merged file1.txt and file2.txt into combined.txt"); 
  
   fclose(pointer1); 
   fclose(pointer2); 
   fclose(pointer3); 
   return 0; 
}

Is there a way to output the described situation? I am aware that E0F refers to the end of a file, and is likely causing an issue. Is there a similar condition for an end of a line (like E0L)?


Edit: Changed char ch to int ch.

Ad

Answer

First, if you have a Unix-like system, the paste command already does that. Next as you want to process lines, you should use fgets. Here you have to loop over input files one line at a time, copy the lines to the output file without the newline, and add the new line after copying everything.

As the processing for both input files is the same, and as I am lazy, I wrote a function to only write it once. In the end code could be:

FILE *copyline(FILE *in, FILE *out) {
    char line[256];
    if (in != NULL) {
        for (;;) {       // loop if the line is larger that sizeof(line)
            if (NULL == fgets(line, sizeof(line), in)) { // EOF on file1
                fclose(in);
                in = NULL;
                break;
            }
            size_t end = strcspn(line, "\n");
            if (end != 0) fwrite(line, 1, end, out);   // smth to write
            if (end != strlen(line)) break;       // \n found: exit loop
        }
    }
    return in;
}
int main()
{
    FILE *pointer1 = fopen("file1.txt", "r");
    FILE *pointer2 = fopen("file2.txt", "r");
    FILE *pointer3 = fopen("combined.txt", "w");
    const char sep[] = " ";          // a separator between lines of both file

    if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
    {
        puts("Could not open files");
        exit(0);
    }

    for (;;) {
        pointer1 = copyline(pointer1, pointer3);
        fwrite(sep, strlen(sep), 1, pointer3);
        pointer2 = copyline(pointer2, pointer3);
        if (pointer1 == NULL && pointer2 == NULL) break;
        fputc('\n', pointer3);  // if smth was written, add a newline
        printf(".");
    }

    printf("Merged file1.txt and file2.txt into combined.txt");

    fclose(pointer3);
    return 0;
}
Ad
source: stackoverflow.com
Ad