Home > Blockchain >  How to copy lines up to a certain character from one text file into another in C?
How to copy lines up to a certain character from one text file into another in C?

Time:12-20

I have a text file, "input", in which some lines contain the character '$'. I want to copy this file into a new text file, "output", but with all the lines truncated after (and including) the '$' character (if present).

I have tried the following:

while (fgets(line, LINE_LENGTH, input) != NULL)
{
    strcpy(tmp_line, line);
    cmt_ptr = strchr(tmp_line, '$');
    if (cmt_ptr != NULL)
    {
        *cmt_ptr = '\n';
    }
    fputs(tmp_line, output);
}

This compiles, but all the text after '$' in each line gets copied into a new line.

I then tried this:

while (fgets(line, LINE_LENGTH, input) != NULL)
{
    strcpy(tmp_line, line);
    cmt_ptr = strchr(tmp_line, '$');
    if (cmt_ptr != NULL)
    {
        strtok(tmp_line, '$');
    }
    fputs(tmp_line, output);
}

but I get an error message saying "Access violation reading location".

Can someone please advise me on how to correct the code?

CodePudding user response:

Below code is insufficient as only the $ is substituted with a '\n'. To shorten the string, set a null character. @Some programmer dude

if (cmt_ptr != NULL)
{
    *cmt_ptr = '\n';
    cmt_ptr[1] = '\0';  // Add
}

Alternative approach: Use different ways to print when a $ is found. No tmp_line needed.

while (fgets(line, LINE_LENGTH, input) != NULL) {
  char *cmt = strchr(line, '$');
  if (cmt) {
    int length = cmt - line;
    printf("%.*s\n", length, line);  // Print limited character array.
  } else {
    fputs(line, output);
  }
}

CodePudding user response:

Using fgets is over-complicating the issue, since there's no need to read full lines. Just read one character at a atime. eg:

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

FILE * xfopen(const char *path, const char *mode);

int
main(int argc, char **argv)
{
        FILE *input = argc > 1 ? xfopen(argv[1], "r") : stdin;
        FILE *output = argc > 2 ? xfopen(argv[2], "w") : stdout;
        enum { print, noprint } state = print;
        int c;
        while( (c = getc(input)) != EOF ){
                switch( c ){
                case '$':
                        state = noprint;
                        break;
                case '\n':
                        state = print;
                }
                if( state == print ){
                        putc(c, output);
                }
        }

        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;
}
  • Related