2

This is my code. I'm trying to read a two-dimensional array from a data file, but I'm getting rubbish. What's wrong?

void read_array(int masyvas[][m])
{
    FILE *fp;
    if ( (fp=fopen("test.dat","wb+"))==NULL)
    {
        printf ("error \n");
        system("pause");
        exit (1);
    } 
    printf("reading file\n");
    int x, y;
    for( x = 0; x < n; ++x ) 
    {
        for( y = 0; y < m; ++y ) 
        {
            fread(&masyvas[x][y], sizeof(int),1,fp );
            printf( "%d ", masyvas[x][y] );
        }
        printf( "\n" ); 
    }
}
1
  • You should describe the data file a bit better. Is it a binary file or an ASCII file? If binary, is it stored big endian or little endian? Is there a header that describes the size of the 2d array? Make sure the sizeof(int) is the same on your system as in the file. etc. Commented Feb 5, 2014 at 18:36

3 Answers 3

2

You aren't checking the fread() calls; that's always a mistake.

The rest of your trouble is that "wb+" mode does truncate to zero length or create binary file for update, which is probably not what you wanted.

Replace "wb+" with "rb+" (open binary file for update (reading and writing)) which does not truncate the file.

Since you opened the file in the function, you should also fclose() it in the function. And since you never do anything with the file except read it, you don't really need the update mode, either.

Sign up to request clarification or add additional context in comments.

Comments

1

You are currently opening your file as wb+ mode. You want to open it for reading: rb+. Please see the following on fopen.

For better readability and understanding, why not following an approach like such:

  • Read the file line by line (using getline).
  • Once you read a line, simply tokenize it (using strtok).
  • Now that you have tokens for that line, you can populate the array in your application.
  • Repeat step 1-3 until EOF.

Note: This assumes that you are reading a text file and that it contains delimiters between each entry that you wish to populate your array with (e.g. 1 2 3 4 5\n, may represent one line in the file where '1', '2', '3' are values to be stored and a \n ends the line).

2 Comments

It's a binary file, opened with "wb+" mode.
Note that to use getline() etc, you need a text file, not a binary file. Of course, any such answer is predicated on the data file being a binary file; if it is actually a text file, what you suggest is probably much better.
0

You're code sample doesn't compile.

Assuming that you're trying to read a binary file containing integers in native-byte order, something like the following should do you. Instead of reading it integer, by integer, why not just slurp it in in one fell swoop?

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

#define ROWS 10
#define COLS  5

void read_array( int buf[ROWS][COLS] )
{
  int   x   = 0 ;
  int   len = 0 ;
  int   cnt = ROWS*COLS ; // number of ints we can handle
  FILE *fp  = fopen("test.dat", "rb" ) ; // open the file for reading in binary mode

  if ( NULL == fp ) 
  {
    printf ("error \n");
    system("pause");
    exit (1);
  } 

  printf("slurping the file\n");
  len = fread(buf,sizeof(int),cnt,fp) ;
  printf( "slurped!\n") ;

  printf( "loaded %d full rows" ,  len/COLS , len%COLS > 0 ? 1 : 0 ) ;
  if ( len%COLS > 0 )
  {
    printf( "and one partial row having %d columns." , len%COLS ) ;
  }
  printf("\n" ) ;

  for ( x = 0 ; x < ROWS ; ++x )
  {
    int y ;
    printf( "row %d: " , x ) ;
    for ( y = 0 ; y < COLS ; ++y )
    {
      printf( "%d " , buf[x][y] ) ;
    }
    printf( "\n" ) ;
  }

  return ;
}

int main( int argc, char* argv[] )
{
  int buf[ROWS][COLS] ;
  memset( buf , (char)0 , sizeof(buf) ) ;
  read_array( buf ) ;
  return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.