简体   繁体   中英

Having issues with fread and fwrite when writing some characters and a struct to a file and reading them back

I want to write three characters to a file, then a struct, then one more character. Finally I would like to read the character before the struct, the struct itself, the character after the struct and display them on the screen.

 struct stuff{
   int a;
   int b;
};

int main(){

  FILE * fp = fopen("input.txt", "w+");
  char charA = 'z';
  char charB = 's';
  char charC = 'q';
  char charD = 'e';

  //create a struct of type stuff
  stuff s;
  s.a = 123;
  s.b = 2111;

 //fwrite three first chars
  fwrite(&charA, 1, sizeof(char), fp);
  fwrite(&charB, 1, sizeof(char), fp);
  fwrite(&charC, 1, sizeof(char), fp);
  //fwrite the struct
  fwrite(&s, 1, sizeof(struct stuff), fp);
  //fwrite the last char
  fwrite(&charD, 1, sizeof(char), fp);

  //read the char before the struct, the struct itself,
  // and the char after the struct
  char expectedCharC;
  stuff expectedStructS;
  char expectedCharD;

  fseek(fp, sizeof(struct stuff) + sizeof(char), SEEK_END);
  fread(&expectedCharC, 1, sizeof(char), fp);
  fread(&expectedStructS, 1, sizeof(struct stuff), fp);
  fseek(fp, sizeof(char)*3 + sizeof(struct stuff), SEEK_SET);
  fread(&expectedCharD, 1, sizeof(char), fp);

  cout<<expectedCharC<<" "<<expectedStructS.a<<" ";
  cout<<expectedStructS.b<<" "<<expectedCharD<<endl;

  fclose(fp);

  return 0;
}

Instead of this result:

q 123 2111 e

I get this result:

4197174 0 e

I don't know what I'm doing wrong. I'm writing bytes to the file, reading them back and displaying them on the screen. What goes wrong?

thank you in advance

Wow, lots of problems in your code. Let's tackle them one by one.

  1. As mentioned by unwind, the mode you're using to open the file seems to be incorrect as to what you're trying to do. For one, you're trying to read from a file that is opened for write-only .

  2. You're using fwrite wrongly. It goes fwrite(pointer to data, size of each data, number of data, FILE pointer); .

  3. You're using fseek wrongly. I see you're confused with the offset parameter. This offset defines a signed distance from the origin specified as the last argument to fseek . Therefore, if you're at SEEK_END , you should be moving backwards by having your offset be a negative number.

I've done these changes myself and now it works. Output: q 123 2111 e

Here's a nice little website for you too. Helped me with your problem.

Thank you for reading.

First, as has been pointed out, you must open the file in binary mode. Even then, just dumping the bytes of a struct means that you won't be able to read it correctly some time in the future. But as long as you're reading from the same process, it should be OK.

The real problem is what you are doing with all of the fseek : before the first fread , you do an fseek beyond the end of the file. Any read from that position is guaranteed to fail. You really should check the status of the file, and ensure that the fread has succeeded before accessing any of the values you read. If it failed, accessing the variables (at least those in stuff ) is undefined behavior; most likely, you'll get some random garbage.

Your first fseek should probably be to the beginning of the file, or else:

fseek( fp, -(sizeof( stuff ) + 4), SEEK_BEG);

If you've just read the struct, then the second fseek is unnecessary as well. (In your case, it means that the final 'e' is correctly read.)

You must open your file in binary mode for this to work.

FILE * fp = fopen("input.txt", "wb+");
                                 ^
                                 |
                                blam!

Your wanted result is also a bit unclear, shouldn't it start with the three characters 'z' , 's' and 'q' , and then have the integers? Note that the integers are likely to appear byte-swapped if you're on a little-endian machine.

To help debug the code, you should add return-value checking to all I/O calls, since I/O can fail. Also note that sizeof (char) is always 1 , so it's not very beneficial to write it like that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM