cfilestreamfgetsfputs

How to read from file and write another in c


I have a input file like this:

This is 1nd Line.
This is 2nd Line.
This 3rd Line.

And I need to output files like

OddLines.txt:

This is 1nd Line.
This 3rd Line.

EvenLines.txt:

This is 2nd Line.

Here is my code. And not working as I wanted.

    char buf[256];
    int ch;
    int lines;
    lines = 1;

    FILE *myFile = fopen(argv[1], "r");

    if (myFile == NULL) {
        printf("Open error \n");
        exit(-1);
    }

    FILE *outFile = fopen("oddlines.txt", "w");
    FILE *outFile1 = fopen("evenlines.txt", "w");

    while (fgets(buf, sizeof(buf), myFile) != NULL) {
        if (ch == '\n')
            lines++;
        else
        if ((lines % 2) == 0)
            fputs(buf, outFile1);
        else
            fputs(buf, outFile);
    }
    fclose(myFile);
    fclose(outFile);
    fclose(outFile1);
}

Solution

  • It is unclear whether you want the output files to contains the lines from the input file or if these lines must be concatenated, stripping the newlines.

    You code does not work because the test if (ch == '\n') has undefined behavior, as ch is uninitialized. Hence the line counter is not properly updated and all lines go into one of the files.

    Counting the lines is actually not as simpler as counting the iterations of the loop as some lines in the input file might be longer than the length of the array used by fgets(). You should update the line counter after writing by testing if the line just written actually contained a newline character.

    Here is a modified version:

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char *argv[]) {
        char buf[256];
        int lines = 1;
        FILE *myFile, *outFile, *outFile1;
    
        if (argc < 2) {
            printf("Missing argument\n");
            return 1;
        }
        if ((myFile = fopen(argv[1], "r")) == NULL) {
            printf("Open error for %s\n", argv[1]);
            return 1;
        }
        if ((outFile = fopen("oddlines.txt", "w")) == NULL) {
            printf("Open error for %s\n", "oddlines.txt");
            return 1;
        }
        if ((outFile1 = fopen("evenlines.txt", "w")) == NULL) {
            printf("Open error for %s\n", "evenlines.txt");
            return 1;
        }
    
        while (fgets(buf, sizeof(buf), myFile) != NULL) {
            if (lines % 2 == 0)
                fputs(buf, outFile1);
            else
                fputs(buf, outFile);
    
            /* if a full line was read, increment the line number */
            if (strchr(buf, '\n')
                lines++;
        }
        fclose(myFile);
        fclose(outFile);
        fclose(outFile1);
        return 0;
    }
    

    Here is a simpler version that does not use fgets():

    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
        int c, out;
        FILE *myFile, *outFile[2];
    
        if (argc < 2) {
            printf("Missing argument\n");
            return 1;
        }
        if ((myFile = fopen(argv[1], "r")) == NULL) {
            printf("Open error for %s\n", argv[1]);
            return 1;
        }
        if ((outFile[0] = fopen("oddlines.txt", "w")) == NULL) {
            printf("Open error for %s\n", "oddlines.txt");
            return 1;
        }
        if ((outFile[1] = fopen("evenlines.txt", "w")) == NULL) {
            printf("Open error for %s\n", "evenlines.txt");
            return 1;
        }
    
        out = 0; /* current output file is "oddlines.txt" */
        while ((c = getc(myFile)) != EOF) {
            putc(c, outFile[out]);
            if (c == '\n')
                out = 1 - out;  /* change current output file */
        }
        fclose(myFile);
        fclose(outFile[0]);
        fclose(outFile[1]);
        return 0;
    }
    

    If you wish to strip vowels from a third output file, just include <string.h>, open that file to FILE *noVowelFile and add a test in the while loop:

        out = 0; /* current output file is "oddlines.txt" */
        while ((c = getc(myFile)) != EOF) {
            if (strchr("aeiouAEIOU", c) == NULL) {
                putc(c, noVowelFile);
            }
            putc(c, outFile[out]);
            if (c == '\n')
                out = 1 - out;  /* change current output file */
        }