0

I am facing problem with read and write functions in C++ and C also.

When I input 2 or more name and ids in my code it writes it perfectly to the file but when I read the file with fread it show some weird behavior it prints same value of ids as I enter for different inputs but for name it prints the same string for all inputs with different length which I entered last.

Example:

Input:

2     
aaa 1      
bbbb 2   

Output:

ID 1 Name bbb
ID 2 Name bbbb

It should print like:

ID 1 Name aaa
ID 2 Name bbbb

My code:

#include <bits/stdc++.h>
using namespace std;

struct person 
{ 
  int id; 
  string fname; 
}; 

int main () {
             
    FILE *outfile;
    struct person input; 
    int num,ident;
    string sname;        
    
    outfile = fopen ("C:\\Users\\Amritesh\\Desktop\\students.txt","w+");
    
    if (outfile == NULL) 
    { 
        fprintf(stderr, "\nError opend file\n"); 
        exit (1); 
    } 
    
    scanf("%d",&num);
    
    for(int i=0;i<num;i++){
    
        cin >> sname;
        scanf("%d",&ident);
    
        struct person student = {ident,sname};
    
        fwrite (&student, sizeof(struct person), 1, outfile);
    }
    
    fseek(outfile,0,SEEK_SET);
    
    while(fread(&input, sizeof(struct person), 1, outfile)) {   
        cout << "ID " << input.id << "  Name " <<input.fname << endl;
    }
           
    fclose (outfile);       
    return 0;
} 

Thanks for any answer in advance.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • Please edit the question to indent it properly :) – kesarling He-Him Aug 11 '20 at 13:14
  • Try to use ofstream and getline in C++ – kesarling He-Him Aug 11 '20 at 13:15
  • And don't tag spam. If you're coding C++, tag it C++ – klutt Aug 11 '20 at 13:15
  • 2
    You cannot use `fread` and `fwrite` with structs that contain `std::string` objects. Use an ifstream and ofstream and perform line-based IO correctly. – Botje Aug 11 '20 at 13:17
  • It shows weird behavior because a std::string likely has internal pointers to memory allocated on the heap. You can't save and restore such an object the way you are doing because the pointers will be invalid when you restore and you are not saving the data that the pointers point to. – drescherjm Aug 11 '20 at 13:22
  • 2
    You may wan't to read about this topic: [https://isocpp.org/wiki/faq/serialization](https://isocpp.org/wiki/faq/serialization) – drescherjm Aug 11 '20 at 13:26
  • 3
    PS, please don't use `bits/stdc++.h`. See [this Q&A](https://stackoverflow.com/a/31816096/201787). – metal Aug 11 '20 at 13:29
  • 2
    Not to mention [`using namespace std;`](https://stackoverflow.com/q/1452721/6865932). – anastaciu Aug 11 '20 at 13:31
  • Also, `scanf()` of (potentially malformed) input without checking return code -> undefined behavior waiting to happen. Your `num` and `ident` may be used uninitialized. – DevSolar Aug 11 '20 at 13:43
  • Please reply what should I do now to solve this problem –  Aug 11 '20 at 13:53
  • Serialize your class using text instead of binary serialization. You probably also want to move to use `c++` iostreams instead of fread / fwrite. The link I gave above on serialization explains your options. – drescherjm Aug 11 '20 at 14:41
  • When using binary I/O, my suggestion is to write the text size first, followed by the text. This allows you to allocate the string variable correctly (since you know the size), then read in the text using block reading. This same concept can be applied to variable length fields. – Thomas Matthews Aug 11 '20 at 15:18

0 Answers0