简体   繁体   English

在将一些字符和结构写入文件并将其读回时遇到fread和fwrite问题

[英]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之前的字符,struct本身,struct之后的字符并在屏幕上显示它们。

 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. 正如unwind所提到的,你用来打开文件的模式似乎是不正确的。你正在尝试做什么。 For one, you're trying to read from a file that is opened for write-only . 首先,您尝试从仅为只写的文件中读取

  2. You're using fwrite wrongly. 你错误地使用了fwrite It goes fwrite(pointer to data, size of each data, number of data, FILE pointer); 它是fwrite(pointer to data, size of each data, number of data, FILE pointer); .

  3. You're using fseek wrongly. 你错误地使用了fseek I see you're confused with the offset parameter. 我看到你对offset参数感到困惑。 This offset defines a signed distance from the origin specified as the last argument to fseek . 此偏移量定义了从指定为fseek的最后一个参数的origin符号距离 Therefore, if you're at SEEK_END , you should be moving backwards by having your offset be a negative number. 因此,如果您处于SEEK_END ,则应将您的offset设为负数,从而向后移动。

I've done these changes myself and now it works. 我自己完成了这些更改,现在它可以工作了。 Output: q 123 2111 e 输出: 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. 即使这样,只是转储struct的字节意味着将来某个时候你将无法正确读取它。 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. 真正的问题是你正在对所有的fseek做什么:在第一个fread之前,你做了一个超出文件末尾的fseek 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. 您真的应该检查文件的状态,并确保在访问您读取的任何值之前fread已成功。 If it failed, accessing the variables (at least those in stuff ) is undefined behavior; 如果失败,访问变量(至少是那些stuff )是未定义的行为; most likely, you'll get some random garbage. 最有可能的是,你会得到一些随机垃圾。

Your first fseek should probably be to the beginning of the file, or else: 你的第一个fseek可能应该是文件的开头,否则:

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

If you've just read the struct, then the second fseek is unnecessary as well. 如果你刚刚阅读了结构,那么第二个fseek也是不必要的。 (In your case, it means that the final 'e' is correctly read.) (在您的情况下,这意味着正确读取了最终的'e' 。)

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? 你想要的结果也有点不清楚,不应该从三个字符'z''s''q' ,然后有整数? 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. 为了帮助调试代码,您应该为所有I / O调用添加返回值检查,因为I / O可能会失败。 Also note that sizeof (char) is always 1 , so it's not very beneficial to write it like that. 另请注意, sizeof (char)始终为1 ,因此编写它并不是非常有益。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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