C语言 C中的二进制文件读/写

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15752546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:54:33  来源:igfitidea点击:

Binary file reading/writing in C

cfilestructbinary

提问by VZKiss

So I have an input.bin file which contains the following

所以我有一个 input.bin 文件,其中包含以下内容

IK-SZH;jdl72u;John Doe;2013-03-28 11:05
IK-GRR;kat91n;Jane Doe;2013-03-21 15:41
IK-GRR;oat62f;Jane Doe;2013-03-24 08:08

What I am doing is to read it into a struct. Doing some stuff with the data. Add/Delete lines. Then i would like to write the content of the structure back to the input.bin file in the same format as above.

我正在做的是将它读入一个结构体。用数据做一些事情。添加/删除行。然后我想以与上面相同的格式将结构的内容写回 input.bin 文件。

But instead of appearing as it is above. It's like this (no spaces):

但不是像上面那样出现。是这样的(没有空格):

IK-SZH NUL jdl72u NUL John Doe NUL NUL NUL NUL NUL 2013-03-28 NUL NUL NUL IK-GRR NUL kat91n NUL Jane Doe NUL NUL NUL NUL ...

When I re-read the file (with the NULs) It only puts the 1st line into the struct

当我重新读取文件(使用 NUL)时,它只将第一行放入结构中

My code

我的代码

typedef struct foo {
    char kid[7];    
    char jid[7];    
    char name[21];  
    char time[20];  

} Foo;

Foo foo[200];
FILE* fp;
int size;

------- File reader

-------文件阅读器

void read(char* filename){
    fp = fopen(filename, "rb"); 
    int i = 0;

    while (!feof(fp)) {

        if (fp==NULL){perror("File opening error\n"); exit(1);}

        fscanf(fp,"%[^;]; %[^;]; %20[^\;]; %s\n", foo[i].kid, foo[i].jid,
                foo[i].name, foo[i].time);
        i++;
    }

    size = i;

    print();

    fclose(fp);
}


void print(){
    int i;
    for (i = 0; i < size; ++i){
        printf("%s\t %s\t %s\t %s\n", foo[i].kid, foo[i].jid,
               foo[i].name, foo[i].time);
    }
}

----- Writer

----- 作家

void write(){
    char str[1000];

    FILE* f = fopen("input.bin", "wb");
    fseek(f, 0, SEEK_SET);
    int i;
    for (i = 0; i < jel_size; i++)
            fwrite(&foo[i], sizeof(struct foo), 1, f);
    fclose(f);

}

Tried this, but this didn't write anything to the file:

试过这个,但这没有向文件写入任何内容:

    char str[1000];
    sprintf(str,"%s;%s;%s;%s\n", jelent[i].kazon,
                    jelent[i].jazon,jelent[i].nev,  jelent[i].ido );

        write(f,&str,sizeof(str))!=sizeof(str);

回答by Jonathan Leffler

Your structure definition is:

您的结构定义是:

typedef struct foo
{
    char kid[7];    
    char jid[7];    
    char name[21];  
    char time[20];  
} Foo;

The code that writes the structures to the file is in write():

将结构写入文件的代码位于write()

for (i = 0; i < jel_size; i++)
    fwrite(&foo[i], sizeof(struct foo), 1, f);

If the structures are intialized with all bytes zero, then for the first row of data you mention:

如果结构用所有字节初始化为零,那么对于您提到的第一行数据:

IK-SZH;jdl72u;John Doe;2013-03-28 11:05

we can infer that the structure contains:

我们可以推断出该结构包含:

IK-SZH
IK-SZH NUL jdl72u NUL John Doe NUL NUL NUL NUL NUL 2013-03-28 NUL NUL NUL 
jdl72u
void write(void)
{
    FILE *fp = fopen("input.bin", "w");
    if (fp != 0)
    {
        for (int i = 0; i < jel_size; i++)
            fprintf(fp, "%s;%s;%s;%s\n", foo[i].kid, foo[i].jid, foo[i].name, foo[i].time);
        fclose(fp);
    }
}
John Doe
void read(const char *filename)
{
    FILE *fp = fopen(filename, "rb"); 
    if (fp != 0)
    {
        for (i = 0; fread(&foo[i], sizeof(foo[i]), 1, fp) == 1; i++)
            ;
        fclose(fp);
        size = i;
    }
}
##代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码####代码## 2013-03-28 11:05##代码####代码####代码####代码##

which more or less agrees with what you say the file contains:

这或多或少与您所说的文件包含的内容一致:

##代码##

By my reckoning, you're missing a few NULs after the name and the time and one NUL after the date.

根据我的估计,您在名称和时间之后缺少几个 NUL,在日期之后缺少一个 NUL。

If you want text output, you will have to format the data in write()using fprintf()analogous to the fscanf()statement you have in the read()function. You should probably return a status from the function to indicate whether it was successful. You can argue for checking that fclose()was successful, too.

如果您想要文本输出,您必须write()使用fprintf()类似于fscanf()您在read()函数中的语句来格式化数据。您可能应该从函数返回一个状态以指示它是否成功。您也可以争辩说检查fclose()是否成功。

##代码##

If you want binary output, you should use binary input in read(). Again, you should consider returning an indication of success or failure; avoiding global variables is good, too.

如果你想要二进制输出,你应该在read(). 同样,您应该考虑返回成功或失败的指示;避免全局变量也很好。

##代码##

Either technique will work; trying to use one on output and the other on input is going to lead to chaos and confusion.

两种技术都行;试图将一个用于输出而另一个用于输入将导致混乱和混乱。

Note that functions read()and write()are used by POSIX with a different interface. While you stick with Standard C, the names are fair for you to use, but you'd probably be better off with alternative names, such as reader()and writer()or foo_read()and foo_write().

请注意,POSIX 使用具有不同接口的函数read()write()。虽然您坚持使用标准 C,但这些名称对您来说是公平的,但您可能最好使用替代名称,例如reader()andwriter()foo_read()and foo_write()

回答by Sava Vrane?evi?

https://gist.github.com/anonymous/5288805

https://gist.github.com/anonymous/5288805

Changed code just a bit, commented, and also tested, so it works for sure.

稍微更改了代码,进行了注释并进行了测试,因此它可以肯定有效。