【问题标题】:fread/fwrite a struct to/from a file in Cfread/fwrite a struct to/from a file in C
【发布时间】:2015-04-01 14:07:19
【问题描述】:

我在使用 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 

【问题讨论】:

  • 如果你想要“可读”的输出,你可以切换到fprintffscanf函数。顺便提一句。 “直接在磁盘上”排序是个坏主意,除非你的内存绝对不足。
  • 您的结构在编写它们时不会清除 char[33] 字段中的多余字符,因此它们充满了当时内存中的任何垃圾。
  • 缺少的元素应该是因为一些fwrite()s 仍在缓冲中。在写和读之间调用fflush(f)(并检查fread()的结果)
  • @IngoLeonhardt 这不应该是相关的 - 缓冲只影响 other 程序是否可以看到未刷新的数据。
  • @user4419802 不幸的是,fread/fwrite 的使用是强制性的,以及在磁盘上进行排序.. 使用打印和扫描以及在 RAM 中进行所有操作会使事情变得更容易,但我已经完成的任务收到的限制..

标签: c


【解决方案1】:
asdf11  orange  26  skin   

windows可能会将txt文件中的26视为EOF

【讨论】:

    【解决方案2】:

    有没有办法让它变成纯文本,还是必须这样?

    是的,它必须是这样,因为当它被写入时,文件被内存中的数据填充。所以它总是这样,即可读和不可读字符的组合。

    为了了解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 个结构对象,然后使用 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-12-27
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 2022-11-09
      • 2022-12-28
      • 2022-12-19
      • 2022-12-02
      • 2022-12-02
      相关资源
      最近更新 更多