Reading an array from a file

Go To StackoverFlow.com

1

I am back to C from Java and C#. I am stuck with the following simple program attempting to read two arrays from a file with a function. Can anyone point out where am I messing up?

Compiler says: error: invalid operands to binary * (have ‘int *’ and ‘int *’)

The file format is

    4
    1   2   3   4
    23  23  14  11

My ReadFromFile function needs to fill buffers A and B from the file.

#include<stdio.h>

void ReadFromFile (const char* file_name, int *A, int *B, int *length)
{
    FILE* file = fopen (file_name, "r");
    fscanf (file, "%d", length);            
    int i;
    for(i = 0; i < length; i++)
    {
        fscanf (file, "%d", A+i); 
    }  
    for(i = 0; i < length; i++)
    {
        fscanf (file, "%d", B+i); 
    }   
    fclose (file);        
}

int main()
{
    int *A; int *B; int length;
    ReadFromFile("input.txt", A, B, &length);

    return 0;
}
2012-04-04 07:03
by blitzkriegz
Is that really the error message? What line does it occur on - David Grayson 2012-04-04 07:05
The error message says that you are trying to multiply two int*, e.g. A * B in main. You don't show any line which does that. In any case, change it to (*A) * (*B) - Jon 2012-04-04 07:06
Line: nt *A; int *B; int length - blitzkriegz 2012-04-04 07:07


1

void ReadFromFile (const char* file_name, int *A, int *B, int *length)
/* ... */
    for(i = 0; i < length; i++)
    {
        fscanf (file, "%d", A+i); 
    }

You have passed in a single integer A from main(), but here you are trying to access completely unrelated memory. Same goes for B. Did you mean to allocate A and B as arrays?

e.g. change:

int *A; int *B; int length;

to

int A[100], B[100], length;

or something similar. (Perhaps dynamically allocate the arrays once you know how many you need -- or allocate them with malloc(3) and grow them with realloc(3) if you need to.)

2012-04-04 07:10
by sarnold
Here I can get to know the length only after reading it from the file. Can't I defer the allocation to inside the function (after reading length) - blitzkriegz 2012-04-04 07:13
If you wanted to make it two passes, you could read through (and discard) all the input, calculate the size you need, allocate the arrays, and then re-read all the data into the arrays. More common, though (think of getting input from a pipe or socket or otherwise not wanting to re-read data off a disk) is to make an initial allocation, fill the arrays a bit, and then grow the arrays once it is clear that you need to allocate more space - sarnold 2012-04-04 07:14


1

int main()
{
    int A; int B; int length;
    ReadFromFile("input.txt", &A, &B, &length);

    return 0;
}

Try using A and B as variables not pointers and call the function with the addresses.

I'm not sure if thats the Issue. But give it a try.

Sorry I was confused by the int pointers. I guess what you want is int[] A what is in fact the same as int* A. But then you have to allocate some memory for the array or initialize it with a given size.

2012-04-04 07:06
by Tarion
I need A and B as array of integers (buffers), not integer - blitzkriegz 2012-04-04 07:10
Updated answer - but there are others that provide you working code - Tarion 2012-04-04 07:12


1

In your function you use A+i that accesses places in memory not allocated by you. In other words: you need a call to malloc first to get the memory.

Think about your structure here: You have address variables A and B but you never pointed them to the address of allocated memory. If you want to do this BEFORE your function you need to know the length of the array. If you want to do it IN your function, you need to pass the address of A and B to assign to it:

void ReadFromFile (const char* file_name, int** A, int** B, int* length)
{
  FILE* file = fopen (file_name, "r");
  fscanf (file, "%d", length);
  *A = (int*) malloc(length * sizeof(int))
  // now use (*A)+i

You would then change main

int* A; int* B; int length;
ReadFromFile("input.txt", &A, &B, &length);
2012-04-04 07:07
by HWende
How to call ReadFromFile here? I mean I need to have that address of address of something to pass right - blitzkriegz 2012-04-04 07:15
I added it to the post - HWende 2012-04-04 07:24


1

First of all A and B are pointers to junk, you need to allocate space if you actually want to store something (or expect a Segmentation fault or memory corruption).

It's complaining about your for loops. length is never initialized so you're sending a pointer to junk data anyway (or it's never populated in read from file).

i < length isn't valid (in that sense) because you're comparing an int value to an address or int * (which doesn't make sense). You might mean i < *length; because length is a pointer and needs to be dereferenced for its actual value.

2012-04-04 07:07
by Jesus Ramos
Yes I understand that. I need to read the length from the file to allocate space. How to do that - blitzkriegz 2012-04-04 07:08
you can use lseek and go to SEEK_END to find the length of the file in bytes and use that as an estimate or allocate some space and call realloc whenever you run out and dynamically expand the space - Jesus Ramos 2012-04-04 07:10


1

When calling your function you should give an address reference e.g. &A and &B

And this is how you should read a text file appropriately :)

FILE *file = fopen(file_name, "r");
while(file != EOF){
    fscanf(...)
}

EDIT:

You don't need to use double pointers. Simply initialize in main() integers Int A,B and give your method them addresses.

2012-04-04 07:07
by Bip
Note that int A,B won't quite cut it -- blitz wants arrays of data. The +1 is for the idiomatic file reading, which is difficult to get right, and starting from a known idiomatic recipe is well worth it. : - sarnold 2012-04-04 07:17
Ads