You are doing IO by character. It will be useless and painful SLOW, even with buffered streams.
Take advantage of the fact that your data is stored in your files as strings with zero completion.
Assuming you alternate the lines with nul-terminated from each file and run on the POSIX platform so that you can just enter mmap() to enter the files:
typedef struct mapdata { const char *ptr; size_t bytes; } mapdata_t; mapdata_t mapFile( const char *filename ) { mapdata_t data; struct stat sb; int fd = open( filename, O_RDONLY ); fstat( fd, &sb ); data.bytes = sb.st_size; data.ptr = mmap( NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0 ); close( fd ); return( data ); } void unmapFile( mapdata_t data ) { munmap( data.ptr, data.bytes ); } void mergeFiles( const char *file1, const char *file2, const char *output ) { char zeroByte = '\0'; mapdata_t data1 = mapFile( file1 ); mapdata_t data2 = mapFile( file2 ); size_t strOffset1 = 0UL; size_t strOffset2 = 0UL; char *iobuffer = memalign( 64UL * 1024UL, 1024UL * 1024UL ); memset( iobuffer, 0, 1024UL * 1024UL ); int fd = open( output, O_RDWR | O_TRUNC | O_CREAT | O_DIRECT, 0644 ); FILE *outputfile = fdopen( fd, "wb" ); setvbuf( outputfile, iobuffer, _IOFBF, 1024UL * 1024UL ); for ( ;; ) { fputs( data1.ptr + strOffset1, outputfile ); fwrite( &zeroByte, 1, 1, outputfile ); fputs( data2.ptr + strOffset2, outputfile ); fwrite( &zeroByte, 1, 1, outputfile ); strOffset1 += 1 + strlen( data1.ptr + strOffset1 ); strOffset2 += 1 + strlen( data2.ptr + strOffset2 ); if ( ( strOffset1 >= data1.bytes ) || ( strOffset2 >= data2.bytes ) ) { break; } } fclose( outputfile ); unmapFile( data1 ); unmapFile( data2 ); }
I did not check for errors at all. You will also need to add the appropriate header files.
Please also note that the file data is NOT considered an exact multiple of the size of the system page, thus ensuring that NUL bytes are displayed after the contents of the file. If the file size is an exact multiple of the page size, you must mmap() add an extra page after the contents of the file to make sure that there is a NUL byte to complete the last line.
Or you can rely on the fact that there is a NUL byte as the last byte of the contents of the file. If this ever turns out to be wrong, you are likely to get either SEGV or corrupted data.