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