我想写一个文件的三个字符,然后是一个结构,然后再写一个字符。 最后,我想读取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
我不知道我做错了什么。我正在向文件写入字节,将其读回并在屏幕上显示。出了什么问题?
提前谢谢
答案 0 :(得分:2)
正如unwind所提到的,你用来打开文件的模式似乎不正确,你正在尝试做什么。例如,您正在尝试从只写打开的文件中读取。
您错误地使用了fwrite
。它是fwrite(pointer to data, size of each data, number of data, FILE pointer);
。
您错误地使用了fseek
。我发现你对offset
参数感到困惑。此偏移量定义了从指定为origin
的最后一个参数的fseek
有符号距离。因此,如果您位于SEEK_END
,则应该通过将offset
设为负数来向后移动。
我自己完成了这些更改,现在它可以正常工作了。输出:q 123 2111 e
这也是一个很好的小website。帮助我解决你的问题。
感谢您的阅读。
答案 1 :(得分:1)
首先,正如已经指出的那样,您必须以二进制文件打开文件
模式。即便如此,只需转储struct
的字节即可
你曾经在一段时间内无法正确阅读它
未来。但只要你从同一个过程中读取它,就可以了
应该没问题。
真正的问题是你正在对所有fseek
做什么:
在第一个fread
之前,你会在fseek
之后完成fread
文件。任何从该位置的读取都将保证失败。
你真的应该检查文件的状态,并确保
在访问您的任何值之前stuff
已成功
读。如果失败了,访问变量(至少是那些变量)
fseek
)是未定义的行为;最有可能的是,你会得到一些
随机垃圾。
您的第一个fseek( fp, -(sizeof( stuff ) + 4), SEEK_BEG);
可能应该是文件的开头,或者
否则:
fseek
如果您刚刚阅读了结构,那么第二个'e'
就是
不必要的。 (在你的情况下,它意味着最后的
正确阅读{{1}}。)
答案 2 :(得分:0)
您必须以二进制模式打开文件才能生效。
FILE * fp = fopen("input.txt", "wb+");
^
|
blam!
你想要的结果也有点不清楚,不应该从三个字符'z'
,'s'
和'q'
开始,然后有整数?请注意,如果您使用的是小端机器,则整数可能会出现字节交换。
为了帮助调试代码,您应该为所有I / O调用添加返回值检查,因为I / O可能会失败。另请注意,sizeof (char)
始终为1
,因此编写此类内容并不是非常有益。