繁体   English   中英

从C中的文件读取/写入结构

[英]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.

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