Jump to content

file merge line by line [in c]

iWearKiltz
Go to solution Solved by iWearKiltz,

See my edit. Try using a logical OR instead of AND

the OR came up with an interesting file lol - definitely wrong. however you gave me an epiphany

attempting some things now, thanks for replying

 

 

To solve the issue of one file not being completely read, i added a few lines of code afterwards:

while ((fgets(x, 999, file_in) != 0))  fprintf(file_out, "%s", x);while ((fgets(y, 999, file_in2) != 0))  fprintf(file_out, "%s", y);

This meant that if the individual statements alone weren't at the end, they would continue to write to the file. SUCCESS!! :D

Hey guys, I'm working on an assignment (this is part 2 of it for anyone that has seen me post in here before).

The assignment is to have two files merged line by line:

file 1 line 1

file 2 line 1

file 1 line 2

file 2 line 2 etc

 

I've got it to work for a file which has short lines (reading in text files, the lines can go on for quite a while), but then it incorrectly enters data from file 2 (misses starting character and also doesn't finish first line and then the loop doesn't continue to EOF). When I switch around so that file 2 is read first, it only enters in up to a  point (first line of this file is a long line, multiple page scrolls).

 

heres some screenshots:

post-16255-0-80908400-1418479826_thumb.p

post-16255-0-29393500-1418479831_thumb.p

 

heres the code

//loop for merging the two files line by lineint z, a=0; //int a for boolean identification of which file is currently being read from (0 = file 1, 1 = file 2)char x, y;while (((x = fgetc(file_in)) != EOF) && ((y = fgetc(file_in2)) != EOF)) { if (a == 0)  {  //write file 1 character to file 3  fputc(x, file_out);   if (x == '\n') //if file 1 character is new line, switch to reading: from file 2   {   a = 1;   }  }  else if (a == 1)   {   //write file 2 character to file 3   fputc(y, file_out);   if (y == '\n') //if file 2 character is new line, switching reading: from file 1     {   a = 0;     }    }elseprintf("there was an error"); }

 

heres the test files:

FILE 1:

thank you laurie

that was super helpful
 
email start
Hi Laurie,
 
Good to hear                         from you.
 
Did some test:
 
If you have the following keyboard layout:
 
 
email end
notepad end
 
 
FILE2:
microsoft being microsoft decided to make things complicated by introducing a 'safer' version of fopen (and scanf etc) by putting '_s' on the end of them. This changes the format of the arguments and generally makes less sense (or at least to me) in comparison to the standard fopen.
 
now there are ways to get around the _s bit, but as this is for a university assignment, I'm trying to avoid that due to the fact that i suspect that they want me to use the more 'secure' fopen variety...
 
thanks for your help though

 

Please help :P!

Edited by iWearKiltz
Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

Why dont use fgets?

Link to comment
Share on other sites

Link to post
Share on other sites

Why dont use fgets?

where?

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

where?

you read line from one file and write it in output.txt. Than read line from second file and write it in output. and repeat.

You could also read from those files interchangeably and use strcat() to fill one string and than later write that whole string to output.txt

Link to comment
Share on other sites

Link to post
Share on other sites

you read line from one file and write it in output.txt. Than read line from second file and write it in output. and repeat.

You could also read from those files interchangeably and use strcat() to fill one string and than later write that whole string to output.txt

but then that uses strings and stuff, and yeah... was trying to avoid that because I'm not the best at strings, but if that is the only way (or better way) then i will do it

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

but then that uses strings and stuff, and yeah... was trying to avoid that because I'm not the best at strings, but if that is the only way (or better way) then i will do it

I will try to code this for you :)

just wait for few minutes

Link to comment
Share on other sites

Link to post
Share on other sites

I will try to code this for you :)

just wait for few minutes

thank you :)

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

thank you :)

#include <stdio.h>#include <stdlib.h>int main(){    FILE *file1 = fopen("file1.txt", "r");    FILE *file2 = fopen("file2.txt", "r");    FILE *output = fopen("output.txt", "w");    char str1[300];    char str2[300];    while((fgets(str1, 300, file1) != 0) && (fgets(str2, 300, file2) != 0)){            fprintf(output, "%s%s", str1, str2);    }    fclose(file1);    fclose(file2);    fclose(output);    return 0;}

file1.txt

file1row1file1row2file1row3file1row4

file2.txt

file2row1file2row2file2row3file2row4

dont forget do add one blank line at end of file1 and file2 txt files

It supports lines that have up to 300 characters. If you want it to support more replace every 300 with how much you want :)

Link to comment
Share on other sites

Link to post
Share on other sites

#include <stdio.h>#include <stdlib.h>int main(){    FILE *file1 = fopen("file1.txt", "r");    FILE *file2 = fopen("file2.txt", "r");    FILE *output = fopen("output.txt", "w");    char str1[300];    char str2[300];    while((fgets(str1, 300, file1) != 0) && (fgets(str2, 300, file2) != 0)){            fprintf(output, "%s%s", str1, str2);    }    fclose(file1);    fclose(file2);    fclose(output);    return 0;}

file1.txt

file1row1file1row2file1row3file1row4

file2.txt

file2row1file2row2file2row3file2row4

dont forget do add one blank line at end of file1 and file2 txt files

It supports lines that have up to 300 characters. If you want it to support more replace every 300 with how much you want :)

 

this is fantastic, thanks for your help. i've met gets before, but never fgets. it's always good to expand my knowledge with this kind of stuff

 

[when using the same file for file 1 and file 2 - so its just repeated text file of itself]

the only issue I'm having right now (which as soon as I've clicked post I'm going to attempt to resolve) is that the last line of both text files is printed on the same line (as the code will see EOF rather then \n and so won't put it on a new line)

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

this is fantastic, thanks for your help. i've met gets before, but never fgets. it's always good to expand my knowledge with this kind of stuff

 

[when using the same file for file 1 and file 2 - so its just repeated text file of itself]

the only issue I'm having right now (which as soon as I've clicked post I'm going to attempt to resolve) is that the last line of both text files is printed on the same line (as the code will see EOF rather then \n and so won't put it on a new line)

I told you to add one extra empty line in file1 and file2

(its only needed in file1 but its ok to put in both)

Link to comment
Share on other sites

Link to post
Share on other sites

I told you to add one extra empty line in file1 and file2

(its only needed in file1 but its ok to put in both)

yeah, for some reason i scanned over that and only realised after posting that comment, sorry!

 

i've solved it anyways by just putting in a boolean style identifier which once EOF is reached, a new line is put in.

 

thanks for all your help

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

I told you to add one extra empty line in file1 and file2

(its only needed in file1 but its ok to put in both)

For some reason it's missing out the first character of some lines (and i can't see any consistency) 

post-16255-0-58978900-1418487377_thumb.p

post-16255-0-85584600-1418487455_thumb.p

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

I told you to add one extra empty line in file1 and file2

(its only needed in file1 but its ok to put in both)

 

Now getting an issue where the file out ends as soon as one file ends (every line from each file needs to be put into file out)

post-16255-0-47873300-1418490550_thumb.p

post-16255-0-67901900-1418490614_thumb.p

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

That is due to logical AND (&&) in the while condition.

while((fgets(str1, 300, file1) != 0) && (fgets(str2, 300, file2) != 0)){    fprintf(output, "%s%s", str1, str2);}

In order to continue, both fgets must not return zero. If either one does return a zero, then it'll evaluate to false and end the loop.

 

So you need to change the code so it doesn't do that. You could try using a logical OR (||) however I'm not familiar enough with C to know if that will run properly. The str of the empty file may be empty and it may be fine, or it could cause weird behaviour.

while((fgets(str1, 300, file1) != 0) || (fgets(str2, 300, file2) != 0)){    fprintf(output, "%s%s", str1, str2);}
Link to comment
Share on other sites

Link to post
Share on other sites

That is due to logical AND (&&) in the while condition.

while((fgets(str1, 300, file1) != 0) && (fgets(str2, 300, file2) != 0)){    fprintf(output, "%s%s", str1, str2);}

In order to continue, both fgets must not return zero. If either one does return a zero, then it'll evaluate to false and end the loop.

okay, i understand the logical AND. But the point i was trying to make was that the 'file out' was ending when there was still strings to be written from 'file 1'. 'file 2' has ended, and so that shouldn't be printing anymore (which is whats happening.. kinda), but its then dropping out the program just because one has happened. (Acting more like a logical OR gate as opposed to an AND gate)

 

Any idea on how to fix this?

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

okay, i understand the logical AND. But the point i was trying to make was that the 'file out' was ending when there was still strings to be written from 'file 1'. 'file 2' has ended, and so that shouldn't be printing anymore (which is whats happening.. kinda), but its then dropping out the program just because one has happened. (Acting more like a logical OR gate as opposed to an AND gate)

 

Any idea on how to fix this?

See my edit. Try using a logical OR instead of AND

Link to comment
Share on other sites

Link to post
Share on other sites

See my edit. Try using a logical OR instead of AND

attempting some things now, thanks for replying

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

See my edit. Try using a logical OR instead of AND

the OR came up with an interesting file lol - definitely wrong. however you gave me an epiphany

attempting some things now, thanks for replying

 

 

To solve the issue of one file not being completely read, i added a few lines of code afterwards:

while ((fgets(x, 999, file_in) != 0))  fprintf(file_out, "%s", x);while ((fgets(y, 999, file_in2) != 0))  fprintf(file_out, "%s", y);

This meant that if the individual statements alone weren't at the end, they would continue to write to the file. SUCCESS!! :D

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

Wouldn't that just print all of 1 file then all of the other? Not mixing them.

no, because there is still the while loop from before (with the AND && in it). due to file pointers, after the program has exited that while loop, it goes onto the next while loop and will print as long as its not EOF. if it is, then it will go onto the next while loop and print that. Nothing gets reprinted as the file pointers haven't been reset to the start

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

I didn't added support for situation when one file has more lines as other as I didn't knew how you want to handle that.

But it could be done too.

Link to comment
Share on other sites

Link to post
Share on other sites

I didn't added support for situation when one file has more lines as other as I didn't knew how you want to handle that.

But it could be done too.

yeah i think i've achieved it with the code above (marked solved)

 

thanks for all your input - you've helped a lot!

Spoiler

Gaming/Engineering PC: -i7 6700K, 4-4.2GHz "Eleanor" -ASUS ROG HERO VIII MOBO -16GB DDR4 3000MHz Corsair (2x8GB) -Gigabyte Windforce 980Ti OC edition (1405MHz GPU clock) -H110i GT Corsair CPU Water cooler -980GB Sandisk Ultra II SSD -Corsair 450D ATX Case -RM850i Corsair PSU (Modular) -28” 4K Samsung -27” 1080p Samsung 

Link to comment
Share on other sites

Link to post
Share on other sites

yeah i think i've achieved it with the code above (marked solved)

 

thanks for all your input - you've helped a lot!

yay you did it :)

Link to comment
Share on other sites

Link to post
Share on other sites

no, because there is still the while loop from before (with the AND && in it). due to file pointers, after the program has exited that while loop, it goes onto the next while loop and will print as long as its not EOF. if it is, then it will go onto the next while loop and print that. Nothing gets reprinted as the file pointers haven't been reset to the start

Oh I see. I didn't realize you were still using the other loop. Glad you solved your problem :)

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×