I currently have to add, and make it so it goes in an order like this
content of file 1
content of file 2
content of file 1
content of file 2
its currently only writing the contents of one text file into the output file, i cant see where i'm going wrong so any help is greatly appreciated.
**** Edit, hi done some digging and found that this exact question has already been answered, didnt want to get in trouble with mods and couldnt delete, thanks all
You are not storing the stream pointers returned by fopen() and you are not interleaving lines from file1 and file2. Here is how to fix these issues:
...
// file 3
printf("Please enter the name of the output file : ");
if (scanf("%s", file3) != 1) {
printf("input error\n");
exit(1);
}
FILE *OpenFile = fopen(file1, "r");
FILE *OpenFile2 = fopen(file2, "r");
FILE *OpenFile3 = fopen(file3, "w");
if (OpenFile == NULL || OpenFile2 == NULL || OpenFile3 == NULL) {
perror("Error opening files");
printf("Press any key to exit!\n");
exit(1);
}
int c1 = 0, c2 = 0;
while (c1 != EOF || c2 != EOF) {
if (c1 != EOF) {
/* copy a line from file1 */
while ((c1 = fgetc(OpenFile)) != EOF && c1 != '\n') {
fputc(c1, OpenFile3);
}
fputc('\n', OpenFile3);
}
if (c2 != EOF) {
/* copy a line from file2 */
while ((c2 = fgetc(OpenFile)) != EOF && c2 != '\n') {
fputc(c2, OpenFile3);
}
fputc('\n', OpenFile3);
}
}
printf("The two files were successfully merged into %s\n", file3);
fclose(OpenFile);
fclose(OpenFile2);
fclose(OpenFile3);
return 0;
You need to alternate your fgetc calls, not do each loop all at once.
int file2_ok = 1, file_ok = 1;
while (file_ok && file2_ok) {
if (file2_ok) {
c = fgetc(OpenFile2);
if (c == EOF) {
file2_ok = 0;
} else {
fputc(c, OpenFile3);
}
}
if (file_ok) {
c = fgetc(OpenFile);
if (c == EOF) {
file_ok = 0;
} else {
fputc(c, OpenFile3);
}
}
}
This assumes that the two files have the same number of characters. The question doesn't indicate how they should be merged if they don't match up evenly.
This merges alternates lines of two text files. The input files and the output file are program arguments.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
FILE *OpenFile;
FILE *OpenFile2;
FILE *OpenFile3;
char buffer[10000]; // hopeful
int finished = 0;
if(argc < 4) {
exit(1);
}
OpenFile = fopen(argv[1], "rt"); // "t" is for MSVC
OpenFile2 = fopen(argv[2], "rt");
OpenFile3 = fopen(argv[3], "wt");
if(OpenFile == NULL || OpenFile2 == NULL || OpenFile3 == NULL) {
exit(1);
}
while(finished != 3) {
if(fgets(buffer, sizeof buffer, OpenFile) != NULL) {
fputs(buffer, OpenFile3);
}
else {
finished |= 1;
}
if(fgets(buffer, sizeof buffer, OpenFile2) != NULL) {
fputs(buffer, OpenFile3);
}
else {
finished |= 2;
}
}
fclose(OpenFile);
fclose(OpenFile2);
fclose(OpenFile3);
return 0;
}
Input file 1:
File 1 line 1
File 1 line 2
File 1 line 3
File 1 line 4
Input file 2:
File 2 line 1
File 2 line 2
Output file 3:
File 1 line 1
File 2 line 1
File 1 line 2
File 2 line 2
File 1 line 3
File 1 line 4
The solution could be more efficient if it took notice of the finished status instead of calling fgets after any file has reached EOF.
Related
int main()
{
char ch;
int word_count = 0, in_word = 0;
char file_name[MAX_LEN];
/* Pointer for both the file*/
FILE *fpr, *fpw;
/* Opening file INPUT.txt in “r” mode for reading */
start:
printf("Enter a file name: ");
scanf("%s", file_name);
fpr = fopen(file_name, "r");
/* Ensure INPUT.txt opened successfully*/
if (fpr == NULL)
{
system("cls");
printf("Could not open the file %s\n", file_name);
goto start;
}
while ((ch = fgetc(fpr)) != EOF) {
{
printf("%c",ch);
}
if(ch == ' ' || ch == '\t' || ch == '\0' || ch == '\n') {
if (in_word) {
in_word = 0;
word_count++;
}
} else {
in_word = 1;
}
}
printf("In the file %s:\n", file_name);
printf("Number of words: %d.\n", word_count);
/* Opening file OUTPUT.txt in “w” mode for writing*/
fpw= fopen("OUTPUT.txt", "w");
/* Ensure OUTPUT.txt opened successfully*/
if (fpw == NULL)
{
puts("Output file cannot be opened");
}
/*Read & Write Logic*/
while ((ch = fgetc(fpr)) != EOF)
{
fputc(ch, fpw);
}
/* Closing both the files */
fclose(fpr);
fclose(fpw);
return 0;
}
Why is it not printing in the output.txt file? And how can I also print the words in the output file?
There must be a conflict between the while function before printing the input. Or maybe there is something reading before the output then having conflict with another one, when I remove the while function (count words) it shows the product in the output.
You read from fpr until you reach EOF, then try to read from it again.
You need to rewind the file to the beginning for the second fgetc() loop to produce anything.
I'm trying to copy the elements from a file to another if the line is an odd number;
for example I have in first file:
6
5 6 8
3
6 9 32
And the output should be
5 6 8
6 9 32
but I get nothing.
Here is my code:
int main() {
FILE *data_input = fopen("data.in", "r");
FILE *data_out = fopen("data.out", "w");
char str;
int nr = 0;
if (data_input == NULL || data_out == NULL)
printf("error");
while ((str = fgetc(data_input)) != EOF) {
str = fgetc(data_input);
if (str == "\n")
nr++;
if (nr % 2 != 0)
fputc(str, data_out);
}
fclose(data_input);
fclose(data_out);
return 0;
}
You don't need to read another time after the while. By doing that you are discarding half the characters (You read 2 but only write one).
You compare with with '\n' (with single quotes, not double).
You should initialize nr with one, since the first row probably isn't the count as the number 0.
int main() {
FILE *data_input = fopen("data.in", "r");
FILE *data_out = fopen("data.out", "w");
char str;
int nr = 1;
if (data_input == NULL || data_out == NULL)
printf("error");
while ((str = fgetc(data_input)) != EOF) {
if (str == '\n')
nr++;
if (nr % 2 != 0)
fputc(str, data_out);
}
fclose(data_input);
fclose(data_out);
return 0;
}
First, what do you start counting from? 0 or 1? The following code starts from zero, so the first line is even.
In addition to the other issues, you emit your newline with the wrong line, which could make the last line of the file incorrectly empty because you emitted the newline for the last even line if it's empty:
int main() {
FILE *data_input = fopen("data.in", "r");
FILE *data_out = fopen("data.out", "w");
char str;
int nr = 0;
if (data_input == NULL || data_out == NULL)
printf("error");
while ((str = fgetc(data_input)) != EOF) {
str = fgetc(data_input);
if (str == "\n")
nr++; <--- this should be *AFTER* emitting the output
if (nr % 2 != 0)
fputc(str, data_out);
}
fclose(data_input);
fclose(data_out);
return 0;
}
would be better as
int main() {
FILE *data_input = fopen("data.in", "r");
FILE *data_out = fopen("data.out", "w");
int nr = 0;
if (data_input == NULL || data_out == NULL)
printf("error");
// note that this is now easier to read and -
// importantly - to *debug* along with being
// **MUCH** less bug-prone
for (;;) {
int str = fgetc(data_input);
if (str == EOF)
break;
if (nr % 2 != 0)
fputc(str, data_out);
if (str == '\n')
nr++;
}
fclose(data_input);
fclose(data_out);
return 0;
}
There are multiple problems:
you do not exit the program if the files cannot be opened
you have a redundant fgets() inside the loop
fgetc() returns an int, do not use a char variable to store it and test for EOF
naming a byte str is very confusing
you should test and output the byte before testing for the end of line: the trailing newline is part of the line.
line numbers are usually 1 based. The first line has number 1 which is odd. From your expected output, you want the lines with an even line number.
Here is a modified version:
#include <stdio.h>
int main() {
FILE *data_input = fopen("data.in", "r");
FILE *data_out = fopen("data.out", "w");
int c;
int lineno = 1; // the first line is line 1
if (data_input == NULL || data_out == NULL) {
printf("error opening files\n");
return 1;
}
while ((c = fgetc(data_input)) != EOF) {
if (lineno % 2 == 0) // output lines with an even line number
fputc(c, data_out);
if (c == "\n") // update the line number after the newline
lineno++;
}
fclose(data_input);
fclose(data_out);
return 0;
}
I am trying to write a program that reads two files from the keyboard and prints line 1 of the first file,
line 1 of the second file, line 2 of the first file, line 2 of the second file, and so on. This is how the output should look like:
File 1 line 1
File 2 line 1
File 1 line 2
File 2 line 2
File 1 line 3
File 1 line 4
My code works and prints the output but with the incorrect format. The output of my code looks like follows:
File 1 line 1
File 2 line 1
File 1 line 2
File 2 line 2File 1 line 3
File 1 line 4
This is my entire code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp, *fp2;
char str[50];
char str2[50];
char firstFile[50], secondFile[50];
int counter;
printf("Enter the first filename: ");
gets(firstFile);
fp = fopen(firstFile, "r");
if (fp == NULL)
{
printf("Can't open the file!\n");
exit(1);
}
printf("Enter the second filename: ");
gets(secondFile);
fp2 = fopen(secondFile, "r");
if (fp2 == NULL)
{
printf("Can't open the file!\n");
exit(1);
}
printf("\n");
while( fgets(str, 30, fp) != NULL)
{
printf("%s", str);
while(fgets(str2, 30, fp2) != NULL){
printf("%s", str2);
break;
}
}
printf("\n");
fclose(fp);
fclose(fp2);
}
I tried implementing a printf("\n") inside the second loop in order to fix the format but it won't work properly. I do not understand why the if statement inside the loop is not working. I tried this with no luck:
while( fgets(str, 30, fp) != NULL)
{
printf("%s", str);
for( int i = 0; fgets(str2, 30, fp2) != NULL; ){
printf("%s", str2);
if(i == 1){
printf("\n");
}
else{
i++;
}
break;
}
}
These are the files I am using to run this code:
https://drive.google.com/file/d/1P6W3dJHVvLOuRjj2NvEbOzic2uFocbKC/view?usp=sharing
https://drive.google.com/file/d/1Z-2OXuLIxwroOgUJaTvTUyhrBguv4ZJH/view?usp=sharing
This problem is not really line oriented, and trying to read one line at a time from each file is more complicated than it needs to be. You only need to read one character at a time, and change the input file from which you are reading whenever you see a newline. eg:
#include <stdio.h>
#include <stdlib.h>
FILE * xfopen(const char *path, const char *mode);
int
main(int argc, char *argv[])
{
FILE *input[2];
int idx = 0;
input[0] = xfopen(argc > 1 ? argv[1] : "input1", "r");
input[1] = xfopen(argc > 2 ? argv[2] : "input2", "r");
int c;
while( (c = getc(input[idx])) != EOF ){
if( c == '\n' ) {
idx = !idx;
}
putchar(c);
}
while( (c = getc(input[!idx])) != EOF ){
putchar(c);
}
return 0;
}
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
*mode == 'r' ? stdin : stdout;
if( fp == NULL ){
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
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.
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;
}
Here's one way to approach it:
#include <err.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
*mode == 'r' ? stdin : stdout;
if( fp == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
int
main(int argc, char **argv)
{
if( argc < 3 ) {
printf("usage: %s file1 file2\n", basename(argv[0]));
}
FILE *pointer1 = xfopen(argv[1], "r");
FILE *pointer2 = xfopen(argv[2], "r");
FILE *current = pointer1;
int ch;
while( ( ch = fgetc(current)) != EOF ) {
if( ch == '\n' ) {
if( current == pointer1 ) {
int k;
current = pointer2;
if( (k = fgetc(current)) != EOF ) {
ungetc(k, current);
ch = ' ';
}
} else {
current = pointer1;
}
}
putchar(ch);
}
if( ferror(current) ) {
err(EXIT_FAILURE, "Error reading %s",
current == pointer1 ? argv[1] : argv[2]);
}
current = current == pointer1 ? pointer2 : pointer1;
while( (ch = fgetc(current)) != EOF) {
putchar(ch);
}
fclose(pointer1);
fclose(pointer2);
return 0;
}
#include <stdio.h>
int main()
{
FILE *pointer1 = fopen("file1.txt", "r");
FILE *pointer2 = fopen("file2.txt", "r");
FILE *pointer3 = fopen("combined.txt", "w");
char ch1, ch2;
if (pointer1 == NULL || pointer2 == NULL || pointer3 == NULL)
{
puts("Could not open files");
return 0;
}
do
{
char c1 = fgetc(pointer1);
char c2 = fgetc(pointer2);
if (feof(pointer1) || feof(pointer2))
break;
while(c1!='\n')
{
fputc(c1,pointer3);
c1=fgetc(pointer1);
if(feof(pointer1)) break;
}
fputc(' ',pointer3);
while(c2!='\n')
{
fputc(c2,pointer3);
c2=fgetc(pointer2);
if(feof(pointer2)) break;
}
fputc('\n',pointer3);
} while (1);
printf("Merged file1.txt and file2.txt into combined.txt");
fclose(pointer1);
fclose(pointer2);
fclose(pointer3);
return 0;
}
This works like you want.
Output: Combined file.txt
file1-line1 file2-line1
file1-line2 file2-line2
file1-line3 file2-line3
I was writing a C program that would read and merge 3 files together (program not complete yet), however, as I was testing I realized the program compiles but the screen on the console remains blank!
Any help is appreciated, especially why is it blank?
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("test");
//open three files for merging
FILE *fp1 = fopen("american0.txt","r");
FILE *fp2 = fopen("american1.txt","r");
FILE *fp3 = fopen("american2.txt","r");
printf("test");
//open file to store the result
FILE *fpm = fopen("words.txt", "w");
//creating an array to save the files data
char c;
char mergedFile[50];
//checking to make sure files are being read
if(fp1 == NULL && fp2 == NULL && fp3 == NULL && fpm == NULL)
{
printf("Could not open one or all of the files.\n");
printf("Exiting program!");
exit(0);
}
printf("test");
//initializing counter values
//inserting data from file into an array
while ((c = fgetc(fp1)) != EOF)
{
fputc(c, mergedFile);
}
while ((c = fgetc(fp2)) != EOF)
{
fputc(c, mergedFile);
}
while ((c = fgetc(fp3)) != EOF)
{
fputc(c, mergedFile);
}
printf("%s",mergedFile[0]);
printf("test");
return 0;
}
Error --> fputc requires a file pointer as it's second argument rather than an array: int fputc ( int character, FILE * stream );
Points to be taken care of:
The size of array should be large enough to contain all the data from these files.
Take care of the format specifier and what it requires in a char array.
What if size of array is less than total size of all files? - Error handling
What if files to be read/written into are in some other directory?
Here is a minimal corrected version:
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000 //ADDED NEW
int main()
{
//open three files for merging
FILE *fp1 = fopen("american0.txt","r");
FILE *fp2 = fopen("american1.txt","r");
FILE *fp3 = fopen("american2.txt","r");
//open file to store the result
FILE *fpm = fopen("words.txt", "w");
//creating an array to save the files data
int c;
int i=0;
char mergedFile[MAX]={0}; //MODIFIED & INITIALIZED
//checking to make sure files are being read
if(fp1 == NULL && fp2 == NULL && fp3 == NULL && fpm == NULL)
{
printf("Could not open one or all of the files.\n");
printf("Exiting program!");
exit(0);
}
//initializing counter values
//inserting data from file into an array
while (((c = fgetc(fp1)) != EOF)&&(i<MAX)) //MODIFIED
{
mergedFile[i++]=c; //MODIFIED
}
while (((c = fgetc(fp2)) != EOF)&&(i<MAX)) //MODIFIED
{
mergedFile[i++]=c; //MODIFIED
}
while (((c = fgetc(fp3)) != EOF)&&(i<MAX)) //MODIFIED
{
mergedFile[i++]=c; //MODIFIED
}
printf("%s",mergedFile); //MODIFIED
return 0;
}