0

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);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Welcome to Stack Overflow. Please read [the help pages](http://stackoverflow.com/help), take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly, if you ask a question related to one programming language, then please don't add irrelevant language tags. – Some programmer dude May 17 '20 at 13:56
  • As a hint: What are the initial values of `lines` and `ch`? How will `ch` even get a value? I also recommend that you do some [*rubber duck debugging*](https://en.wikipedia.org/wiki/Rubber_duck_debugging) of the code inside the loop. Does it really make any sense? – Some programmer dude May 17 '20 at 13:57
  • Do you want the lines to be concatenated into a single line in the output files or to appear as separate lines in the odd and even files? – chqrlie May 17 '20 at 15:17

3 Answers3

0
if (ch == '\n')

This code does not make sense. Do you want to find enter character ? If YES, you can use strcspn function:

int pos = strcspn ( buf, "\n" );

The lines should be initialize by 0 not 1:

    int lines = 0;
    while(fgets(buf, sizeof(buf),myFile))
    {
        lines++;
        int pos = strcspn ( buf, "\n" ); // find the enter character
        buf[pos] = ' '; // add space at the end of string
        buf[pos+1] = '\0';
        if ((lines%2)==0) // if even
            fputs (buf,outFile1); 
        else               // if odd
            fputs (buf,outFile);
    }

You should check the fopen function:

FILE *myFile = fopen(argv[1], "r");
if(!myFile) {return -1;}

FILE *outFile = fopen("oddlines.txt", "w");
if(!outFile) {return -1;}
FILE *outFile1 = fopen("evenlines.txt", "w");
if(!outFile1) {return -1;}

And the condition of command line:

if(argc < 2 ) {
    printf("usage: %s <input_filename>", argv[0]);
    return-1;
}

The complete code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[]) {

    char buf[256];
    int lines = 0;

    if(argc < 2 ) {
        printf("usage: %s <input_filename>", argv[0]);
        return-1;
    }

    FILE *myFile = fopen(argv[1], "r");
    if(!myFile) {return -1;}
    FILE *outFile = fopen("oddlines.txt", "w");
    if(!outFile) {return -1;}
    FILE *outFile1 = fopen("evenlines.txt", "w");
    if(!outFile1) {return -1;}

    while(fgets(buf, sizeof(buf),myFile)!=NULL)
    {
        lines++;
        int pos = strcspn ( buf, "\n" );
        buf[pos] = ' ';
        buf[pos+1] = '\0';
        if ((lines%2)==0)
            fputs (buf,outFile1);
        else
            fputs (buf,outFile);
    }

    fclose(myFile);
    fclose(outFile);
    fclose(outFile1);
}

the input file:

This is 1nd Line.
This is 2nd Line.
This is 3rd Line.
This is 4th Line.
This is 5th Line.
This is 6th Line.

The output file:

$cat evenlines.txt

This is 2nd Line. This is 4th Line. This is 6th Line. 

$cat oddlines.txt

This is 1nd Line. This is 3rd Line. This is 5th Line. 
Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • Is there anyway to do this without using strcspn function? –  May 17 '20 at 14:37
  • in this case you can use `int pos = strlen(buf)-1;` Or you can use a loop to find enter characater – Hitokiri May 17 '20 at 14:40
  • `buf[pos] = ' ';` might overwrite the null terminator if the line is too long or if the file does not en with a newline, causing undefined behavior when writing the no longer null terminated `buf` with `fputs()`. – chqrlie May 17 '20 at 14:56
  • @chqrlie i added the code for adding `\0` character. Thanks for your comment – Hitokiri May 17 '20 at 14:58
  • @Hitokiri: I'm afraid your fix is incorrect: if the line was longer than 255 bytes, `pos` would be equal to `255` and `buf[pos+1] = '\0';` would write beyond the end of `buf`. Furthermore, it would be incorrect to increment `lines` in this case as well as inserting an extra space. – chqrlie May 17 '20 at 15:15
  • How can I add one more loop which detects and deletes vowels letters of each Line and write consonant letters to another txt file? –  May 17 '20 at 15:20
  • @chqrlie in fact, we can define length of array `buf` is equal to `MAX_LEN+1 ` or we add the space character if `pos < 255`. I add space character because the output of OP have the space between two lines. – Hitokiri May 17 '20 at 15:25
  • @Hitokiri: *I add space character because output of OP have the space between two lines.*... but if there is no newline in the buffer, you would be inserting a space in the middle of a long line, not between two lines. – chqrlie May 17 '20 at 15:27
  • @angunav you should create another function, that take the `lines` as the argument then do something you want with `lines`. It's more clear than you add another loop in while loop. – Hitokiri May 17 '20 at 15:28
  • @Hitokiri: why not suggest the use of `strchr()` to the OP who seems unfamiliar with `strcspn()`? – chqrlie May 17 '20 at 15:30
  • @chqrlie i understand your idea. Can you give me a hint for handle this case (if we create another condition for the case that there is not enter character, the code becomes more complicate for OP). Thanks. For `strchr()`. i do not know what function is unfamiliar or familiar for OP. Of course, `strchr` is good function for finding the character in string. – Hitokiri May 17 '20 at 15:36
  • @Hitokiri: It is actually unclear if the OP wants newlines replaced with spaces in the output files, I asked for clarification and did not get an answer. Regarding `strchr()` vs `strcspn()`, I'm afraid the first is at least 100 times more popular than the second, despite efforts to popularize its use to strip the trailing newline left by `fgets()`. – chqrlie May 17 '20 at 15:40
0
if (ch == '\n')

The problem was in this line.

#include <stdio.h>
#include<string.h>
void main() 
{
    int line=1;
    char buf[256];

    FILE *fp, *fp_Odd, *fp_Even;
    fp=fopen("USERS.TXT", "r");

    fp_Odd=fopen("ODD.TXT", "a");
    fp_Even=fopen("EVEN.TXT", "a");

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

    while(fgets(buf, sizeof(buf), fp)!=NULL)
    {
        if(strcmp(buf, "\n")==0)
        line++;

        else if(line%2 != 0)
            fprintf(fp_Odd, "%s", buf);
        else
            fprintf(fp_Even, "%s", buf);

        line++;
    }
    fclose(fp);
}

You can check this code. I have made the necessary changes. Hope you understand.

  • Your code seems incorrect: a blank line will cause `line` to be incremented twice. And why change the filenames and the command line argument handling of the OP's program? – chqrlie May 17 '20 at 15:32
  • No if there is a blank line it will not increment twice. And you can use any filename and command line argument you want. I used used these. – Akshat Jain May 18 '20 at 03:29
0

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 */
    }
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Im kind of beginner so I don't clearly understand expression of out ^= 1; –  May 17 '20 at 15:42
  • @angunav: `out ^= 1;` uses exclusive or to toggle `out` between `0` and `1`. I shall update the answer with a simpler expression. – chqrlie May 17 '20 at 15:44
  • This was really simpler version of others. Thanks. –  May 17 '20 at 16:05
  • @angunav: thank you. Do you mind answering this question: *Do you want the lines to be concatenated into a single line in the output files or to appear as separate lines in the odd and even files?* – chqrlie May 17 '20 at 16:22
  • This is good. I want to lines appear as separate lines in the odd and even files. So Do you mind answering this question: Do you want to help me one more time? How can I add one more loop which detects and deletes vowels letters and writes another output file. I'm trying but I couldn't even write a single line of code. –  May 17 '20 at 16:40
  • @angunav: Do you mean a filter that deletes vowels and writes all other bytes unchanged? You would first need to define what is a vowel. – chqrlie May 17 '20 at 16:42
  • Yes exactly. I need a output like this Ths s 1nd Ln. Ths s 2nd Ln. Ths s 3rd Ln. –  May 17 '20 at 16:45
  • @angunav: I updated the answer. Note that it is up for debate whether `y` is to be considered a vowel or not. Update the code according to your local convention. – chqrlie May 17 '20 at 16:50
  • I'm sorry. Actually I wanted to say I need one more output like outFile[2] = fopen("vowellines.txt", "w") –  May 17 '20 at 17:10
  • @angunav: OK, you would open a third file and output `c` if it is not a vowel. See update. – chqrlie May 17 '20 at 17:18
  • Thanks for everything. You really helped me a lot. –  May 17 '20 at 17:30