Problems with arrays

This is a discussion on Problems with arrays within the C Programming forums, part of the General Programming Boards category; I have been trying to create a program to read a 4 column tab-delineated file into a variably sized array ...

  1. #1
    Registered User
    Join Date
    Sep 2012
    Posts
    3

    Problems with arrays

    I have been trying to create a program to read a 4 column tab-delineated file into a variably sized array and then print the array to the screen, but when I try the code below, it gives me a diagonally symmetrical array, ie [0][1] is the same as [1][0], which is wrong.
    This is my code:
    Code:
    int main ()
    {
        FILE *file_ptr = 0;
    
    
        int nrows;
        nrows=1;
        float a,b;
        int i;
        int j;  
        char data[100];  
        float e,f,c,d; 
        float myarray[10][nrows];
    
    
        printf("Enter location of input file.\n");
        scanf("%s", data);
    
    
        file_ptr = fopen(data, "r");
        for (i=0; !feof(file_ptr); i++)
        {
            fscanf(file_ptr,"%f%f%f%f",&e,&f,&c,&d);
            myarray[0][i]=e;
            myarray[1][i]=f;
            myarray[2][i]=c;
            myarray[3][i]=d;
                   if (e =!NULL){nrows++;}
        }
        fclose(file_ptr);
        
        printf("\n%d data sets retrieved.\n\n",i);
    
    
            for (j=0;j<i;j++)
            {
               printf("%f\t%f\t%f\t%f\n",myarray[0][j],myarray[1][j],myarray[2][j],myarray[3][j]);
            }
        return 0;
    }
    And the data set I am working with is

    13.079 0.051658 0.77359 0.00052980
    14.162 0.051750 0.0097982 0.0019695
    15.888 0.054027 0.80159 0.0019485
    16.191 0.054512 0.62303 8.9929e-05
    17.339 0.055797 0.99587 0.00041386
    18.784 0.056146 0.25421 0.0016562
    19.967 0.056846 0.60045 0.00038078
    20.437 0.058294 0.61663 0.00014638
    21.397 0.058011 0.026190 0.00032348
    22.998 0.059799 0.26090 0.00092712
    23.456 0.059883 0.64564 0.0016402
    24.070 0.060772 0.83006 0.0017486
    25.109 0.060415 0.80091 0.00093706
    26.887 0.061940 0.80918 6.3588e-05
    27.527 0.063505 0.86446 0.0012275
    28.860 0.064270 0.31924 0.0014887
    29.616 0.063735 0.63400 0.0016803
    30.430 0.065634 0.64624 0.00025035
    31.863 0.067435 0.20427 0.00051878
    32.326 0.067050 0.0066200 0.00017732
    33.043 0.068377 0.71793 0.0017101

    What am I doing wrong? I am fairly new to coding, so simple answers would be much appreciated!

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    5,826
    Variable size arrays are not arrays that magically grow when you try to access their elements.

    You need to specify the size of a variable-size array when you create it. The only difference is that the size of a variable size array might not be known until run time. But, when the program is running, the size still has to be known BEFORE the array can be created.

    Also
    Code:
        int nrows;         /* uninitialised, so value of nrows is indeterminate */
        float x[nrows];  /* undefined behaviour.  Accessing nrows is an invalid operation */
    
        ++nrows;    /*   this changes nrows.   It does not resize x */
    Right 98% of the time, and don't care about the other 3%.

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Glyfada,Athens
    Posts
    2,649
    You need to understand some things about 2 dimensional arrays
    Let array be a 2D array
    • When i write array[i][j] i am referring to row i and column j .Each element in a 2D array needs two coordinates to be specifies uniquely.
    • When we want to access 2D arrays,we usually do it with a double for loop,like below
      Code:
           int array[4][4];
           int i,j;
           for(int i=0 ; i<4 ; i++)
           {  
                     for(int j=0 ; j<4 ; j++)
                     {
                                array[i][j]=0;
                      }
            }
      This way i filled up every single cell of the array with zeros.First it will fill the first row(starting from the first element of it),or in other words,array[0][0] will be filled up,then array[0][1] and so on..


    In your code,you have several issues with the arrays.
    [List][*]
    Code:
    float myarray[10][nrows];
    Now you declared a 2D array with 10 rows and nrows columns.Of course the nrows variable's name is not good.Actually it is good,but misued.
    So i suggest you to change it in something like this
    Code:
     float myarray[nrwos][4];
    ,where nrows is the number of rows that are in the text file (.txt) you are reading from and 4 columns why every row in your file has 4 columns
    [*]
    Code:
      
            myarray[0][i]=e;
            myarray[1][i]=f;
            myarray[2][i]=c;
            myarray[3][i]=d;
    first we are reading the very first cell of the array,thus myarray[0][0].then the second cell of the array,thus myarray[0][1] and so on...So this part of code should be changed into this
    Code:
            myarray[i][0]=e;
            myarray[i][1]=f;
            myarray[i][2]=c;
            myarray[i][3=d;
    [*]
    Code:
            for (j=0;j<i;j++)
            {
               printf("%f\t%f\t%f\t%f\n",myarray[0][j],myarray[1][j],myarray[2][j],myarray[3][j]);
            }
    This is wrong and not readable.Please follow my advice and write it like this..
    Code:
            for (i=0;i<4;i++)
            {
                for(j=0;j<4;j++)
                {
                     printf("%f\t",myarray[i][j]);
                } 
                printf("\n");
            }
    Here we use the double for structure to read a 2D array.This is very flexible and easy to use,so i suggest you take a good look at it.The print that changes a line is positioned there,because at this point,the loop is done with every line that it goes through...

    In conclusion
    Code:
    #include <stdio.h>
    
    
    int main ()
    {
        FILE *file_ptr = 0;
    
    
        int nrows;
        nrows=1;
        float a,b;
        int i;
        int j;
        char data[100];
        float e,f,c,d;
        float myarray[4][4];
    
    
        printf("Enter location of input file.\n");
        scanf("%s", data);
    
    
        file_ptr = fopen(data, "r");
        for (i=0; !feof(file_ptr); i++)
        {
            fscanf(file_ptr,"%f%f%f%f",&e,&f,&c,&d);printf("read %f || %f || %f || %f \n",e,f,c,d);
            myarray[i][0]=e;
            myarray[i][1]=f;
            myarray[i][2]=c;
            myarray[i][3]=d;
                   if (e =!NULL){nrows++;}
        }
        fclose(file_ptr);
    
        printf("\n%d data sets retrieved.\n\n",i);
    
    
            for (i=0;i<4;i++)
           {
                     for(j=0;j<4;j++)
                     {
                            printf("%f\t",myarray[i][j]);
                     }
           }
           return 0;
    }

  4. #4
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    383
    Quote Originally Posted by Eleanor Odell View Post
    Code:
        int nrows;
        nrows=1;
    Code:
        float myarray[10][nrows];
    You allocated only 1 row to your array. Arrays in C do not automatically expand when you change the variable that was used in its allocation (in this case, nrows).

    There are a few solutions to this. The easiest is to set nrows to a value at least as large as the maximum number of lines you expect to read from a file. This will limit your program to that number of lines. Another solution is to dynamically allocate and reallocate the array to fit more rows. Use the malloc and realloc functions for this (and you should put rows first in your array, ie myarray[rows][columns]). Another possibility is to change your algorithm so that it doesn't have to store more than one row at a time; perhaps you can print each row as you read it. Then you won't need an array at all.

    Also read FAQ > Why it's bad to use feof() to control a loop - Cprogramming.com

  5. #5
    Registered User
    Join Date
    Sep 2012
    Posts
    3
    Quote Originally Posted by grumpy View Post

    Also
    Code:
        int nrows;         /* uninitialised, so value of nrows is indeterminate */
        float x[nrows];  /* undefined behaviour.  Accessing nrows is an invalid operation */
    
        ++nrows;    /*   this changes nrows.   It does not resize x */
    Thanks, it's a bit better now, but it still puts wrong values into the array and I have no idea where they are coming from...

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,954
    What is your updated code?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Sep 2012
    Posts
    3
    Quote Originally Posted by std10093 View Post

    In conclusion
    Code:
    #include <stdio.h>
    
    
    int main ()
    {
        FILE *file_ptr = 0;
    
    
        int nrows;
        nrows=1;
        float a,b;
        int i;
        int j;
        char data[100];
        float e,f,c,d;
        float myarray[4][4];
    
    
        printf("Enter location of input file.\n");
        scanf("%s", data);
    
    
        file_ptr = fopen(data, "r");
        for (i=0; !feof(file_ptr); i++)
        {
            fscanf(file_ptr,"%f%f%f%f",&e,&f,&c,&d);printf("read %f || %f || %f || %f \n",e,f,c,d);
            myarray[i][0]=e;
            myarray[i][1]=f;
            myarray[i][2]=c;
            myarray[i][3]=d;
                   if (e =!NULL){nrows++;}
        }
        fclose(file_ptr);
    
        printf("\n%d data sets retrieved.\n\n",i);
    
    
            for (i=0;i<4;i++)
           {
                     for(j=0;j<4;j++)
                     {
                            printf("%f\t",myarray[i][j]);
                     }
           }
           return 0;
    }
    Thank you so much, that's way better!

  8. #8
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    383
    Your code has a buffer overrun if you read more than 4 lines from the file (which, I guess, is better than 1 line as before). It also still misuses feof for checking for end of file.

    What are you trying to do with this line?
    Code:
                   if (e =!NULL){nrows++;}
    What that line actually does is sets e to 1 (NULL is 0, so !NULL is 1) and then always increments nrows (which isn't used anymore in the updated code).

    Lastly, what do you think happens when the file cannot be opened for reading?

  9. #9
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Glyfada,Athens
    Posts
    2,649
    Quote Originally Posted by Eleanor Odell View Post
    Thank you so much, that's way better!
    I hope you did not skip my explanation above and jump into the code..Because this is not good for you.Notice that this code is going to work only for 4 rows -text file.You have to adjust it for more.

    Also take a good look at what christop said abou this Also read FAQ > Why it's bad to use feof() to control a loop - Cprogramming.com

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problems with arrays
    By vikingcarioca in forum C Programming
    Replies: 4
    Last Post: 03-31-2009, 07:21 AM
  2. Having problems with arrays
    By pokiepo in forum C Programming
    Replies: 4
    Last Post: 06-18-2008, 01:27 AM
  3. Problems with arrays
    By steffi in forum C Programming
    Replies: 1
    Last Post: 11-16-2007, 03:37 AM
  4. Having problems with 2d arrays
    By newy100 in forum C++ Programming
    Replies: 4
    Last Post: 01-04-2004, 10:46 AM
  5. problems on arrays
    By krithi in forum C Programming
    Replies: 8
    Last Post: 12-25-2002, 06:55 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21