在C中向/从文件中fread / fwrite结构

时间:2015-04-01 14:07:20

标签: 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 

2 个答案:

答案 0 :(得分:0)

asdf11  orange  26  skin   

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

答案 1 :(得分:0)

  

有没有办法让它成为纯文本,或者它必须是那样的?

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

为了理解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是当前在内存中的结构。 &#39; $&#39;只是一个代表驻留在内存中的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;
}