繁体   English   中英

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

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

我想写一个文件的三个字符,然后是一个结构,然后再写一个字符。 最后我想读取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;
}

而不是这个结果:

q 123 2111 e

我得到这个结果:

4197174 0 e

我不知道我做错了什么。 我正在向文件写入字节,将其读回并在屏幕上显示。 出了什么问题?

先感谢您

哇,你的代码中有很多问题。 让我们一个一个地解决它们。

  1. 正如unwind所提到的,你用来打开文件的模式似乎是不正确的。你正在尝试做什么。 首先,您尝试从仅为只写的文件中读取

  2. 你错误地使用了fwrite 它是fwrite(pointer to data, size of each data, number of data, FILE pointer);

  3. 你错误地使用了fseek 我看到你对offset参数感到困惑。 此偏移量定义了从指定为fseek的最后一个参数的origin符号距离 因此,如果您处于SEEK_END ,则应将您的offset设为负数,从而向后移动。

我自己完成了这些更改,现在它可以工作了。 输出: q 123 2111 e

这里也是一个不错的小网站 帮助我解决你的问题。

谢谢你的阅读。

首先,正如已经指出的那样,您必须以二进制模式打开文件。 即使这样,只是转储struct的字节意味着将来某个时候你将无法正确读取它。 但只要你从同一个过程中读取,就应该没问题。

真正的问题是你正在对所有的fseek做什么:在第一个fread之前,你做了一个超出文件末尾的fseek 任何从该位置的读取都将保证失败。 您真的应该检查文件的状态,并确保在访问您读取的任何值之前fread已成功。 如果失败,访问变量(至少是那些stuff )是未定义的行为; 最有可能的是,你会得到一些随机垃圾。

你的第一个fseek可能应该是文件的开头,否则:

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

如果你刚刚阅读了结构,那么第二个fseek也是不必要的。 (在您的情况下,这意味着正确读取了最终的'e' 。)

您必须以二进制模式打开文件才能使其正常工作。

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

你想要的结果也有点不清楚,不应该从三个字符'z''s''q' ,然后有整数? 请注意,如果您使用的是小端机器,则整数可能会出现字节交换。

为了帮助调试代码,您应该为所有I / O调用添加返回值检查,因为I / O可能会失败。 另请注意, sizeof (char)始终为1 ,因此编写它并不是非常有益。

暂无
暂无

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

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