0

I am working on a text file containing integers separated by spaces, for instance:

1 2 57 99 8 14 22 36 98 445 1001 221 332 225 789 1111115 147 0 1 21321564 544 489 654 61266 5456 15 19

I would like to re-format this file to only contain 5 integers in any line but the last, and at most 5 integers in the last line.

My code:

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

int main()
{

FILE *f; // main file (A.txt)
FILE *g; // file copy (B.txt)

// open A.txt to read data
f = fopen("file/path/here/A.txt", "r");
if (f == NULL) {
    printf("Read error.\n");
    fclose(f);
    return -1;
}

// open B.txt to write data
g = fopen("file/path/here/B.txt", "w");
if (g == NULL) {
    printf("Write error.\n");
    fclose(g);
    return -2;
}

int line = 1; // first line in output file
while (!feof(f)) { // not end-of-file
    char number[1000];
    int i = 0;
    for (i = 0; i <= 4; i++)
        if (fscanf(f, "%s", number) == 1) { // one number read
            fprintf(g, "%s", line + i, number);
        }
    line += i;
}

// close files
fclose(f);
fclose(g);

return 0;
}

When I run this in Code::Blocks, I get the 'Segmentation fault (core dumped) Process returned 139' message. I suspect that the problem lies in the 'if' statement and my use of formats. Needless to say, I'm relatively new to C. How might I fix this?

Zelazny
  • 139
  • 5

2 Answers2

1

The simple reason for your segmentation fault is expression fprintf(g, "%s", line + i, number);, in which you state to pass a pointer to a string (i.e. char*), but actually pass a number (i.e. line + i); hence, the value of line + i, which is probably 1, ..., is interpreted as a pointer to memory address 1, which is not allowed to be addressed. It is as if you wrote fprintf(g, "%s", 1), which crashes, too;

So basically change this expression into fprintf(g, "%s", number);, and it should at least not crash (unless you have numbers with more than 999 digits).

There are some other issues in your code, e.g. that you open B.txt for write and assign it to g, but then you test and close the file using variable f. But maybe above "crash solution" brings you forward, such that you can work further on your own. Note that - if B.txt failed opening, then your code would also have crashed because of passing NULL as file stream argument to fprintf.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
-1

The issue is with the use of fscanf and then fprintf.

fscanf knows how to parse a string into a number. E.g. fscanf(f, "%d", &var);. This reads a signed integer from the file handle f into the variable var. This can then be printed with fprintf.

As it stands, the first fscanf slurps the entire input into number (assuming that 1000 char is enough) and the following ones are not expected to be called

levengli
  • 1,091
  • 7
  • 18