1

I'm trying to read some numbers in C from a text file which contains 1000 lines of numbers such as:

-340,495,-153,-910,835,-947  
-175,41,-421,-714,574,-645  
-547,712,-352,579,951,-786  
419,-864,-83,650,-399,171  
...

but when I execute the code I see the i variable starts at 901 instead of 0 so it reads the numbers from the point i=901 to i=999. This is where I am experiencing problems.

I've tried to use a while loop instead of a for loop to avoid an extra i variable:

while(!feof(file_in)){
    fscanf(file_in,"%d%*c%d%*c",&a[0],&a[1]);
    fscanf(file_in,"%d%*c%d%*c",&b[0],&b[1]);
    fscanf(file_in,"%d%*c%d%*c",&c[0],&c[1]);
    printf("A(%d,%d) I=%d\n",a[0],a[1],i);
    printf("B(%d,%d) I=%d\n",b[0],b[1],i);
    printf("C(%d,%d) I=%d\n",c[0],c[1],i);  
}

This is the part of the code I'm having hard time with:

int main(void) {
    FILE *file_in;

    int a[2];
    int b[2];
    int c[2];

    file_in = fopen("triangles.txt","r");

    if (file_in == NULL){
        printf("Can't open file for reading.\n");
        exit(0);
    }
    else{
        for(int i=0;i<1000; i++) {
            fscanf(file_in,"%d%*c%d%*c",&a[0],&a[1]);
            fscanf(file_in,"%d%*c%d%*c",&b[0],&b[1]);
            fscanf(file_in,"%d%*c%d\n",&c[0],&c[1]);
            printf("A(%d,%d) I=%d\n",a[0],a[1],i);
            printf("B(%d,%d) I=%d\n",b[0],b[1],i);
            printf("C(%d,%d) I=%d\n",c[0],c[1],i);  
        }
       fclose(file_in);
    }
    return 0;
}

What I expect:

A(-340,495) I=0  
B(-153,-910) I=0  
C(835,-947) I=0  
A(-175,41) I=1  
...

What I get:

B(-225,-818) I=901  
C(-808,-657) I=901  
A(-279,-34) I=902  
B(-533,-871) I=902  
...
Tungdil
  • 13
  • 4
  • 1
    Note that [`while (!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). – Jonathan Leffler Mar 22 '19 at 22:46
  • Note that if you fail to open the file, you attempt to call `fclose()` with a null pointer. This will not lead to happiness. Only close the file if you successfully opened it. It's often best to "fail quickly" — report the error (on `stderr`, not `stdout`) and exit, leaving the rest of the code one level less indented. – Jonathan Leffler Mar 22 '19 at 22:49
  • What you've provided is fairly close to an MCVE ([MCVE]), but I think you should omit the call to `consitOrigin()` since you don't provide that code. If you find that the program works when you omit that call, then you're showing the wrong place. You should also check the return value from every call to `fscanf()` to ensure you get the values you expect. At the moment, you've no idea when things go wrong. – Jonathan Leffler Mar 22 '19 at 22:54
  • I see. I transferred the fclose statement inside the else part. – Tungdil Mar 22 '19 at 22:55
  • 1
    Moving `fclose()` is the primary alternative; that works too. —— **Are** you testing the `for` loop code or the `while` loop code mainly? I don't see how `i` gets the wrong value with the `for` loop, but if you aren't really using `i` with the `while` loop, and in particular if you forget to initialize it, then you might see 901 instead of 0 as the first value. You still seem to be incrementing `i`, though. – Jonathan Leffler Mar 22 '19 at 22:58
  • Even when I excluded the extra function part to check the data flow from the **fscanf** function **i** still seems to start with a value of 901. I'm mainly using the for loop since I know the length of the text file I'm working with – Tungdil Mar 22 '19 at 23:05
  • 1
    How are you examining the output of the program? If you are just dumping the output to a console, it may simply be that you have exceeded the console's scrollback. Check the console application's settings. – rici Mar 22 '19 at 23:12

1 Answers1

2

I don't think you've yet demonstrated the problem. This is a minor adaptation of your code, reporting errors to stderr, exiting on an error, and so on.

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

int main(void)
{
    int a[2];
    int b[2];
    int c[2];
    const char filename[] = "triangles.txt";
    FILE *file_in = fopen(filename, "r");

    if (file_in == NULL)
    {
        fprintf(stderr, "Can't open file %s for reading.\n", filename);
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < 1000; i++)
    {
        int r1 = fscanf(file_in, "%d%*c%d%*c", &a[0], &a[1]);
        int r2 = fscanf(file_in, "%d%*c%d%*c", &b[0], &b[1]);
        int r3 = fscanf(file_in, "%d%*c%d\n", &c[0], &c[1]);
        if (r1 != 2 || r2 != 2 || r3 != 2)
        {
            fprintf(stderr, "Failed to read data for i = %d: r1 = %d, r2 = %d, r3 = %d\n",
                    i, r1, r2, r3);
            exit(EXIT_FAILURE);
        }
        printf("A(%4d,%4d) I=%d\n", a[0], a[1], i);
        printf("B(%4d,%4d) I=%d\n", b[0], b[1], i);
        printf("C(%4d,%4d) I=%d\n", c[0], c[1], i);
    }
    fclose(file_in);
    return 0;
}

Note that it scrupulously checks the scanning operations, and reports problems if (when?) it encounters them.

Beware of the trailing newline in the format string. When the input is coming from a file, it is OK (not necessary, but OK), but it is a dire UI disaster if a human is ever expected to type the numbers.

Given the data file:

-340,495,-153,-910,835,-947  
-175,41,-421,-714,574,-645  
-547,712,-352,579,951,-786  
419,-864,-83,650,-399,171

I get the output:

A(-340, 495) I=0
B(-153,-910) I=0
C( 835,-947) I=0
A(-175,  41) I=1
B(-421,-714) I=1
C( 574,-645) I=1
A(-547, 712) I=2
B(-352, 579) I=2
C( 951,-786) I=2
A( 419,-864) I=3
B( -83, 650) I=3
C(-399, 171) I=3
Failed to read data for i = 4: r1 = -1, r2 = -1, r3 = -1

The last line appears on standard error, of course; the rest is written on standard output.

I think your problem is not in the code shown, therefore.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I guess the file I'm trying the read is so big that it overflows something because when I execute the code for a relatively small file everything works just fine. Here is the link to the file I'm trying to read [link](https://projecteuler.net/project/resources/p102_triangles.txt) – Tungdil Mar 23 '19 at 07:33
  • I tried an adaptation of the code above (flattening three lines of output per line of input into one line of output per line of input) on your big data file and it worked fine (except that three of the numbers were `-1000` which threw the formatting off; `%5d` instead of `%4d` would have restored uniformity). – Jonathan Leffler Mar 23 '19 at 21:17