Search code examples
arrayscfile-ioio

Reading multiple files with different number of lines


I am trying to read arrays from multiple files, and the array size in each file is different. So what I do is, I try to count the number of lines in the file and then store that as the array size.

For example, I have two .txt files, File_1.txt and File_2.txt which contain the following data:

0.000 300.00
0.054 2623.3
1.000 300.00
0.000 300.00
0.054 2623.3
0.500 1500.0
1.000 300.00

respectively.

Here is the code that I use:

int main()
{
    char filter[1024];
    char filename[60];
    FILE *fp;
    double *T_SR, Z_SR;

    for (int i = 1; i < 3; i++)
    {
        sprintf(filename, "File_%d.txt", i);
        fp = fopen(filename, "r");
        if (fp == NULL)
        {
            exit(1);
        }

        int count = 0;
        for (int j = getc(fp); j != EOF; j = getc(fp))
        {
            if (j == '\n')
            {
                count = count + 1;
            }
        }

        T_SR = (double *)malloc(count * sizeof(double));
        Z_SR = (double *)malloc(count * sizeof(double));

        for (int rows = 0; rows < count; rows++)
        {
            fscanf(fp, "%lf %lf", &Z_SR[rows], &T_SR[rows]);
            printf("%lf %lf\n", Z_SR[rows], T_SR[rows]);
            if (feof(fp))
            {
                break;
            }
        }
    }
}

But instead of printing the given array as output, it prints this:

0.0000 0.0000
0.0000 0.0000

I checked the value of count, it's good. Maybe the problem is simple, but I am not able to find it. Can someone please help?


Solution

  • After you ran the whole file with getc the file indicator will be at the end of the file you must set it back to the beginning before you use fscanf, you can use rewind for that.

    rewind(fp); //<--
    for (int rows = 0; rows < count; rows++)
    {
        //...
    }
    

    Aside from that, other problems exist as Jaberwocky pointed out, among others, like a memory leak issue, and the fact that you don't close your files or check malloc return, here's how your code could look like (with comments):

    double *T_SR, *Z_SR; // fix the pointer issue
    //...
    char line[1024]; // make sure it's larger than the largest line in the file
    
    while (fgets(line, sizeof line, fp)) // fixes the count issue
    {
        // doesn't count empty lines, if there are any
        if (line[0] != '\n')
        {
             count++;
        }
    }
    if(count > 0)
    {
        T_SR = malloc(count * sizeof *T_SR);
        Z_SR = malloc(count * sizeof *Z_SR);
        if(T_SR == NULL || Z_SR == NULL) // check memory allocation
        {
            perror("malloc");
            return EXIT_FAILURE;
        }
    
        rewind(fp);
        for(int rows = 0; fscanf(fp, "%lf%lf", &Z_SR[rows], &T_SR[rows]) == 2; rows++)
        {
             printf("%lf %lf\n", Z_SR[rows], T_SR[rows]);
        }
        free(T_SR); // free the memory, avoids memory leaks
        free(Z_SR);
    }
    fclose(fp); // and close the file
    //...
    

    Live demo