Link to home
Start Free TrialLog in
Avatar of ValidityRules
ValidityRules

asked on

Read items from file into multidimensional array

I am having trouble reading items into a multidimensional array. I have a file that is always in this format below:

3
1.2 2.4
3.5 1.2
0.4 5.6

The top line indicates how many items there are (3) in the file and will be stored to a non-array variable. The remaining lines 2-4 are the items needing to be processed into the array. So 1.2 and 2.4 need to go in array[1][1] and 3.5 and 1.2 go in array[2][2] and so forth so that they correspond to each other.
Avatar of Infinity08
Infinity08
Flag of Belgium image

I'm not sure I understand what you're trying to do.


>> So 1.2 and 2.4 need to go in array[1][1]

You put two values in the same position in the array ? Are you using a struct for that ? Could you show the code you already have ?


>> and so forth so that they correspond to each other.

What do you mean by "correspond" ?
Is there any reason that you're only filling in items on the diagonal of the 2D array ?
Which one you want? C, C++ or C#?
// C++
 
int count;
cin >> count;
map<int,pair<double,double> > items;
 
for (int i = 0; i < count; i++)
{
  double a, b;
  cin >> a >> b;
  items.insert(make_pair(i+1,make_pair(a,b));
}
 
// usage
cout << map[2].first << " " << map[2].second << endl;

Open in new window

Avatar of ValidityRules
ValidityRules

ASKER

Well it's primary zone is C, hoping it would be in C. My goal is to take those values and insert them into the array. So 1.2 will be in column 1 row 1 and 2.4 will be in column 1 row 2. Or for visual purposes array[1.2][2.4]
>> So 1.2 will be in column 1 row 1 and 2.4 will be in column 1 row 2.

That would correspond to the code :
double array[3][2];   /* 3 rows, 2 columns */
 
array[0][0] = 1.2;    /* first row, first column */
array[0][1] = 2.4;    /* first row, second column */
 
array[1][0] = 3.5;    /* second row, first column */
array[1][1] = 1.2;    /* second row, second column */
 
array[2][0] = 0.4;    /* third row, first column */
array[2][1] = 5.6;    /* third row, second column */

Open in new window

Is that what you want to happen ?

Are you sure you need a 2D array ? Why not put the two values in a struct, and make a 1D array of this struct ? It provides a closer coupling of related data, plus it will make the code more clear.


Can you show the code you already have, so we know what it is that you need help with exactly ?
Correct. Now how can I do this by reading those values from a file and then inserting them into the array accordingly? My goal was to read the top most like, then declare the array. Once it's declared, read the remaining lines and insert those into the array
Here is what I have so far
#include <stdio.h>
 
int main()
{
    FILE *fi;
    
	int i, j, x, z;
	int size_arr;
	i=0;
 
    
 
	fi = fopen("input.txt", "r");
	
	sscanf(line, "%3f2", &size_arr);
		
	double a[size_arr][size_arr];	
 
    while (fgets(line,20,fi)!=NULL)
    {
    
        for(i=0; i <= size_arr; i++)
            for (i=0; i <= size_arr; i++)
                a[i][j] = fi;
    	
    }
 
    fclose(fi);
 
    return 0;
}

Open in new window

>>         sscanf(line, "%3f2", &size_arr);

What did you mean by %3f2 ?
What's line ? Is it supposed to be an array of char ?

Did you mean to read from the file using fscanf ? Or did you mean to use fgets first to read a line from the file into a line buffer ?

Did you mean to use %d for an int ?


>>         double a[size_arr][size_arr];

Every row contains two values, so there's no need to have more than 2 columns in the 2D array.
You'll also have to allocate the array dynamically, using calloc for example :

        http://www.cplusplus.com/reference/clibrary/cstdlib/calloc/

Don't forget to free the allocated memory as soon as you don't need it any more :

        http://www.cplusplus.com/reference/clibrary/cstdlib/free/


>>         for(i=0; i <= size_arr; i++)
>>             for (i=0; i <= size_arr; i++)

These nested for loops use the same loop counter. I'm sure that's not what you intended.
You don't even need a loop here, since all you want to do, is read two values from the line and put them in the 2D array at the correct location.

>>                 a[i][j] = fi;

You can't simply assign the FILE* ... you'll need to get the values from the line, and store the values.
Here is my updated code. But it's still not working
#include <stdio.h>
 
int main()
{
    int sum = 0;
    int i, j;
    int num_arr;
    float float_temp;
    
    // Declare the file pointer that we will read from.
    FILE* fin;
    
    // Call the fopen function to open the file numbers.txt for reading.
    fin = fopen("input.txt", "r");
    
    fscanf(fin, "%d", &num_arr);
    
    double arr[num_arr][num_arr];
    
    for(i=0; i <= num_arr; i++)
        for(j=0; j <= num_arr; j++)
        {
            fscanf(fin, "%lf", &float_temp);
            arr[i][j] = float_temp;
        }
        
    fclose(fin);
    
    for(i=0; i <= num_arr; i++)
        for(j=0; j <= num_arr; j++)
        {
            printf(" ", arr[i][j]);
        }
    
    system("PAUSE");
    return 0;
}

Open in new window

You are reading (num_arr+1)^2 numbers. Not num_arr*2. Why?

Just to clarify. By ^2 I mean exponent not XOR.

Your file contains num_arr*2 values, you are reading (num_arr+1)*(num_arr+1).
>>     double arr[num_arr][num_arr];

As I said, you'll need to allocate memory dynamically. See my previous post for more details.
You'll also need only 2 columns. There are num_arr rows and 2 columns.


>>     for(i=0; i <= num_arr; i++)
>>         for(j=0; j <= num_arr; j++)

Same here : num_arr rows, and 2 columns only.

Also note what Let_Me_Be said about the upper limit of the loop counter. The last element in an array of size n, is at index (n - 1), not at index n.
> As I said, you'll need to allocate memory dynamically.
What? This is C not C++ :)
>> > As I said, you'll need to allocate memory dynamically.
>> What? This is C not C++ :)

You mean C99 maybe ? Or a non-standard compiler extension ?
Yes, C99 is the current standard. This concrete feature should be provided by all up to date C compilers.
>> This concrete feature should be provided by all up to date C compilers.

There's a difference between "should" and reality.

gcc has a C99 compilation mode (which is not fully conforming yet : http://gcc.gnu.org/c99status.html), but it's not on by default. By default it's in C90 mode (including certain non standard gcc extensions). Note that gcc has variable size arrays as a non-standard extension (since quite a while), but that doesn't actually count if you're talking about C.

Or worse, afaik, MSVC doesn't support it at all, let alone that it conforms to C99.

So, I wouldn't yet depend on C99 being supported by all compilers ;)
Okay so I got it to work with the following code. and It works flawlessly
int main(void)
{
    int sum = 0;
    int i, j;
    int num_arr;
    double float_temp;
    
    FILE* fin;
    
    fin = fopen("input.txt", "r");
    
    fscanf(fin, "%d", &num_arr);
    printf("%d\n", num_arr);
    
    double arr[num_arr][2];
 
    for(i=0; i < num_arr; i++)
        for(j=0; j < 2; j++)
        {
            if(feof(fin))
                break;
        
            fscanf(fin, "%lf", &float_temp); 
            arr[i][j] = float_temp;
        }
       
    fclose(fin);
    
    for(i=0; i < num_arr; i++)
        for(j=0; j < 2; j++)
        {
            printf("position(%d)(%d)  %.1lf \n", i, j, arr[i][j]);
        }
    
    system("PAUSE");
    return 0;
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial