2

So, I have this array of structs and a file in which I need to copy all information to the struct, can I do something like this? If not how could I do this?

#include <stdio.h>
#include <iostream>

using namespace std;

typedef struct{
      int x;
      int y;
      int z;
}coordinates;

int main(){
     coordinates coordinate[100];
     int i = 0;
     FILE *f;
     f = fopen("file.file","rb");

     if(!f){
        cout << "Error";
        return 0;
     }

     while(!feof(f)){
        fread(coordinate[i],sizeof(coordinates),1,f);
        i++;
     }
     return 0;
}
João Areias
  • 1,192
  • 11
  • 41
  • Learn how to overload the stream operators and use `std::fstream`. Also `while(feof(..))` or anything similar to that is wrong. – Rapptz Jun 23 '15 at 23:33
  • I can't use fstream, the teacher is annoying as hell and won't let us use any function she haven't taught us – João Areias Jun 23 '15 at 23:35
  • "can i do something like this"? You would answer this question your self if you try. Don't forget to change `wb` to `rb`. – Acha Bill Jun 23 '15 at 23:40
  • `fread(coordinate[i]` --> `fread(&coordinate[i]` – BLUEPIXY Jun 23 '15 at 23:40
  • When you want to read then open file with "rb" or "rb+" mode , "wb" mode will erase previously stored data inside file – udit043 Jun 23 '15 at 23:40
  • If you already running this program by file open mode "wb", the contents of the file already has been lost. – BLUEPIXY Jun 23 '15 at 23:48
  • I did change for "rb" the "wb" was just an spelling mistake, it's late where I live and I'm tired :/ if you look up there it's "rb" – João Areias Jun 23 '15 at 23:52
  • 1
    `fread(coordinate[i],sizeof(coordinates),1,f);` `sizeof(coordinates)` is going to try and read 100 coordinates. Use `sizeof(coordinates[0])` – user4581301 Jun 23 '15 at 23:53
  • instead of `while(!feof(f)){` use `while(fread(coordinate[i],sizeof(coordinates[0]),1,f))` fread returns the number of objects read. If it can't read sizeof(coordinates[0]), it returns zero. Since only one was asked for, you should get either 1 (success) or 0 (fail). – user4581301 Jun 23 '15 at 23:59
  • 1
    Which language do you want to do this in C or C++. It makes a lot of difference in how to go about this seemingly simple task. – Martin York Jun 24 '15 at 00:48

5 Answers5

1

Well if you are using C++ (a completely different language to C by the way). You would simply define the input operator for the class.

struct coordinates{
      int x;
      int y;
      int z;

      // Personally I prefer serialization to a straight binary format.
      // It is easy to read and validate by a human
      // and not as brittle as a binary format when anything non
      // trivial happens.
      friend std::istream& operator>>(std::istream& str, coordinates& c)
      {
           return str >> c.x >> c.y >> c.z;
      }
      friend std::ostream& operator<<(std::ostream& str, coordinates const& c)
      {
           return str << c.x << " " << c.y << " " << c.z << " ";
      }
};

Now you can simply read structures from the file:

int main()
{
    std::ifstream data("file.file");

    coordinates  value;
    while(data >> value) {
       std::cout << "I have a set of cordinates\n";
    }

    // To read them into an array (a vector is a resizable array available in C++)
    std::vector<coordinates>   vec;
    std::copy(std::istream_iterator<coordinates>(file),
              std::istream_iterator<coordinates>(),
              std::back_inserter(vec));
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
0

How to write and read struct to binary file

    typedef struct{
      int x;
      int y;
      int z;
}coordinates;

Write to file

 FILE *f;
 f = fopen("test.dat","wb");

 for(int i = 0; i < 3; i++)
 {
    coordinates c;
    c.x = 0;
    c.y = 1;
    c.z= 2;
    fwrite(&c,sizeof(coordinates),1,f);
 }

read back to struct

 FILE *f;
 f = fopen("test.dat","rb");

 if(!f){
    cout << "Error";
    return 0;
 }

 coordinates c;
 while(fread(&c,sizeof(coordinates),1,f))
 {
    cout << c.x << " " << c.y << " "<< c.z << endl;
 }
Acha Bill
  • 1,255
  • 1
  • 7
  • 20
0

Can I retrieve a struct from a file if so how?

Yes, you can. And you can do so using the read and write method. Open file and write the struct in binary mode. Then you can read from the file in binary mode using the read method.

You can use the write method to write a structure directly into a file in binary mode:

#include <iostream>
#include <fstream>
using namespace std;

struct Player {
    int age;
    int score;
};

int main()
{
    // You can write a structure directly into a file.
    // Create an instance of 'Player':
    Player rec;
    rec.age = 10;
    rec.score = 900;

    // Create out file
    fstream out_file("rec.bin",
                     ios::trunc | ios::binary | ios::in | ios::out
                     );

    // write the whole structure into the file
    out_file.write(reinterpret_cast<char*>( &rec ),
                   sizeof( rec )
                   );
}

We typecast to char* in the write and read method because the write method writes each character, each byte, one by one in order. Therefore we cast to char* to refer directly to this set of bytes.


And to read the file use the read method.
Below is an example reading the struct we just wrote into file rec.bin:

#include <iostream>
#include <fstream>
using namespace std;

struct Player {
    int age;
    int score;
};

int main()
{
    fstream in_file("rec.bin", ios::binary | ios::in | ios::out);

    Player in_rec;

    // read in age
    if ( !in_file.read(
          reinterpret_cast<char*>( &in_rec.age ),
          sizeof( in_rec.age )
    ))
    {
        // handle error
    }

    // read in score
    if ( !in_file.read(
          reinterpret_cast<char*>( &in_rec.score ),
          sizeof( in_rec.score )
    ))
    {
        // handle error
    }

    cout << in_rec.age << endl;
    cout << in_rec.score << endl;
}

Output:

10
900
Andreas DM
  • 10,685
  • 6
  • 35
  • 62
0

Use delimiter in cord.txt file , so it will be easy to retrieve coordinates. My code will work good if you have text file in this format

cord.txt
4,5,6,
3,4,5,
7,8,9,   

Code according to above text file format is

typedef struct 
{
 int x;
 int y;
 int z;
}cord;

int main(int argc, char *argv[])
{
  cord cr[100];
  int i,j,k,l;
  j=0;k=0;l=0;
  char numbr[80];char numx[3];char numy[3];char numz[3];
  FILE *p;
  p = fopen("cord.txt","r");
  if(!p) { cout<<"File is missing\n"; }
  while(!feof(p))
  {
    for(i=0;i<80;i++)
    numbr[i]=NULL;
    for(i=0;i<3;i++)
    {
      numx[i]=NULL;
      numy[i]=NULL;
      numz[i]=NULL;
    }

   fgets(numbr,80,p);
   for(i=0;i<strlen(numbr);i++)
   {
      if(numbr[i]!=',')
      {
          if(k==0) {numx[l]=numbr[i];}
          else if(k==1) {numy[l]=numbr[i];}
          else if(k==2) {numz[l]=numbr[i];}
          l=l+1;    
      }
      else
      {
          l=0;
          if(k==0)
          {cr[j].x=atoi(numx);k=k+1;}
          else if(k==1)
          {cr[j].y=atoi(numy);k=k+1;}
          else if(k==2)
          {cr[j].z=atoi(numz);k=0;break;}
      }
   } 
   j=j+1;    
}
fclose(p);

for(i=0;i<j;i++)
 {   
   cout<<cr[i].x<<" "<<cr[i].y<<" "<<cr[i].z<<endl;
 }
cout<<"\n";
return EXIT_SUCCESS;
}

Output will be 4,5,6, 3,4,5, 7,8,9

udit043
  • 1,610
  • 3
  • 22
  • 40
  • 1. That has nothing to do with reading structures from a file. 2. Regarding `while(!feof(p))`, give http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong a read. TL;DR how do you suppose the FILE is going to know it is at the end of the file before reading some of the file? – user4581301 Jun 24 '15 at 00:39
0

This process of writing a struct to a FILE (or more generally, a stream) is called serialization. You can either do it in binary (this is pretty difficult) or in text. The following code performs text serialization on a similar data structure.

int read_coords (FILE * f, coord_t * result);
void write_coords (FILE * f, coord_t const * write_me);

/**
 * Reads a coordinate in the form x,y,z from f into result.
 * Returns non-zero on success
 */
int read_coords (FILE * f, coord_t * result)
{
  // Leading spaces in scanf cause us to elegantly handle weird whitespace
  int read = fscanf (f, " %d , %d , %d", &result->x, &result->y, &result->z);

  return read == 3;
}

void write_coords (FILE * f, coord_t const * result)
{
  fprintf (f, "%d, %d, %d\n", result->x, result->y, result->z);
}

int main (void)
{
  coord_t coord;

  printf ("Gimme Coords: ");
  if (read_coords (stdin, &coord))
  {
    printf ("I got: ");
    write_coords(stdout, &coord);
  }
  else
  {
    printf ("I had an error reading those coords.");
  }

  return 0;
}

PS, it looks like you're in a C class. I suggest avoiding for now. You can mix and match the different I/O methods in the same program, but it makes things confusing.

QuestionC
  • 10,006
  • 4
  • 26
  • 44