[英]fread/fwrite a struct to/from a file in C
我在使用fread / fwrite函数读取和写入文件结构时遇到麻烦。 首先,用fwrite编写的文本对我来说是不可读的,但是从我看来,它的意图是这样工作。 有没有办法将其制成纯文本,或者必须这样?
另一个问题是,当我尝试使用fread函数从该文件读取数据时,几乎没有读取到最后一个元素。
此外,我需要这段代码直接在磁盘上对文件中的数据进行排序。 强制使用fread / fwrite。
#include <stdio.h>
typedef struct camesi {
char camasa[33];
char culoare[33];
int marime;
char material[33];
} cam;
int main() {
FILE *f, *f2;
int i, j, n;
cam a, b, c;
n = 13;
f = fopen ("new.txt", "w+");
f2 = fopen ("asd.txt", "r");
rewind (f2);
for (i = 0; i < n; i++) {
fscanf (f2, "%s%s%d%s", c.camasa, c.culoare, &c.marime, c.material);
printf ("%s\t%s\t%d\t%s\n", c.camasa, c.culoare, c.marime, c.material);
fwrite (&c, sizeof (cam), 1, f);
}
printf ("\n----------------------------------------\n\n");
rewind (f);
for (i = 0; i < n; i++) {
fread (&c, sizeof (cam), 1, f);
printf ("%s\t%s\t%d\t%s\n", c.camasa, c.culoare, c.marime, c.material);
}
return 0; }
这是控制台的输出:
asdf1 blue 45 skin
asdf2 green 43 skin
asdf3 white 49 skin
asdf4 red 47 skin
asdf5 yellow 54 skin
asdf6 purple 13 skin
asdf7 magenta 74 skin
asdf8 pink 41 skin
asdf9 black 97 skin
asdf10 gray 85 skin
asdf11 orange 26 skin
asdf12 violet 64 skin
asdf13 brown 11 skin
----------------------------------------
asdf1 blue 45 skin
asdf2 green 43 skin
asdf3 white 49 skin
asdf4 red 47 skin
asdf5 yellow 54 skin
asdf6 purple 13 skin
asdf7 magenta 74 skin
asdf8 pink 41 skin
asdf9 black 97 skin
asdf10 gray 85 skin
asdf11 orange 85 skin
asdf11 orange 85 skin
asdf11 orange 85 skin
前半部分是从手动创建的* .txt文件读取的数据。
另一半是使用fwrite函数从程序创建的文件中读取的数据。
原始* .txt文件的内容:
asdf1 blue 45 skin
asdf2 green 43 skin
asdf3 white 49 skin
asdf4 red 47 skin
asdf5 yellow 54 skin
asdf6 purple 13 skin
asdf7 magenta 74 skin
asdf8 pink 41 skin
asdf9 black 97 skin
asdf10 gray 85 skin
asdf11 orange 26 skin
asdf12 violet 64 skin
asdf13 brown 11 skin
用fwrite函数创建的文件内容:
asdf1 €M o ёю( Ђ(wїдЂ‚юяяяblue M - skin M `M А&M €ю( HЯПt M asdf2 €M o ёю( Ђ(wїдЂ‚юяяяgreen M + skin M `M А&M €ю( HЯПt M asdf3 €M o ёю( Ђ(wїдЂ‚юяяяwhite M 1 skin M `M А&M €ю( HЯПt M asdf4 €M o ёю( Ђ(wїдЂ‚юяяяred e M / skin M `M А&M €ю( HЯПt M asdf5 €M o ёю( Ђ(wїдЂ‚юяяяyellow M 6 skin M `M А&M €ю( HЯПt M asdf6 €M o ёю( Ђ(wїдЂ‚юяяяpurple M
skin M `M А&M €ю( HЯПt M asdf7 €M o ёю( Ђ(wїдЂ‚юяяяmagenta M J skin M `M А&M €ю( HЯПt M asdf8 €M o ёю( Ђ(wїдЂ‚юяяяpink ta M ) skin M `M А&M €ю( HЯПt M asdf9 €M o ёю( Ђ(wїдЂ‚юяяяblack a M a skin M `M А&M €ю( HЯПt M asdf10 €M o ёю( Ђ(wїдЂ‚юяяяgray a M U skin M `M А&M €ю( HЯПt M asdf11 €M o ёю( Ђ(wїдЂ‚юяяяorange M skin M `M А&M €ю( HЯПt M asdf12 €M o ёю( Ђ(wїдЂ‚юяяяviolet M @ skin M `M А&M €ю( HЯПt M asdf13 €M o ёю( Ђ(wїдЂ‚юяяяbrown M skin M `M А&M €ю( HЯПt M
asdf11 orange 26 skin
Windows可能会将txt文件中的26视为EOF
有没有办法将其制成纯文本,或者必须这样?
是的,它必须是这样的,因为在写入时,文件中充满了内存中的数据。 因此,总是像这样,即可读和不可读字符的组合。
为了理解fread/fwrite
的行为,我将以您的输出为例
asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$
现在,假设上面的代码在内存中,这样asdf1 blue 45 skin
是当前在内存中的结构。 “ $”只是一个分隔符,代表内存中的7个结构。 现在,如果您想使用fread将文件中的数据读取到结构中,那么理想的情况是使用fwrite将文件写入文件,方法是逐个写入每个结构,而在它们之间没有任何额外的字节。 只有这样,才能使用fread()轻松读取它。
为了演示这一点,这是一个简单的程序,该程序首先填充5个struct对象,然后使用fwrite将它们写入文件。 然后,它再次从文件中读取那些写入的结构,然后用该数据填充C结构。
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAX 5
struct camesi {
char camasa[33];
char culoare[33];
int marime;
char material[33];
} myStruct;
int main()
{
int i = 0;
FILE *file = NULL;
//Fill a structure with values
memset(&myStruct, 0, sizeof(myStruct));
memcpy(myStruct.camasa, "asdf1", 5);
memcpy(myStruct.culoare, "blue", 4);
myStruct.marime = 45;
memcpy(myStruct.material, "skin", 4);
//Open the file to write
if ((file = fopen("test.txt", "w+")) == NULL) {
printf("Error opening file to write\n");
return -1;
}
for (i = 0; i < MAX; i++)
fwrite(&myStruct, sizeof(myStruct), 1, file);
fclose(file);
//Open the file for read
if ((file = fopen("test.txt", "r")) == NULL) {
printf("Error opening file for read\n");
return -1;
}
//Clear the myStruct from previous values
memset(&myStruct, 0, sizeof(myStruct));
//Read and display
for (i = 0; i < MAX; i++)
{
fread(&myStruct, sizeof(myStruct), 1, file);
printf("%s\t%s\t%d\t%s\n", myStruct.camasa, myStruct.culoare, myStruct.marime, myStruct.material);
//Clear the myStruct from previous value as we will read again in same object in next iteration
memset(&myStruct, 0, sizeof(myStruct));
}
fclose(file);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.