【问题标题】:C program reading and writing to binary filesC程序读写二进制文件
【发布时间】:2021-06-22 22:06:30
【问题描述】:

您好,这是我第一次使用 C 语言处理二进制文件。

我试图先将数据写入文件,然后再从文件中读取相同的数据。但不知何故,我没有正确读取数据(这就是我的想法),因为我认为文件写入部分没有问题。我在 unix 中完成所有这些工作。

所以基本上我正在尝试从 unix 中的二进制文件写入和读取数据,但我无法正确读取数据。任何帮助,将不胜感激。提前致谢。

我已经附上了下面的代码和输出,所以它是可以理解的:

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
    char data[100];
    if(argc<2){
             printf("Usage: gift <textstring>\n");
     return -1;
            }
            int n = 0;
            int num = 0;
    char data[100];
    if(argc<2){
             printf("Usage: gift <textstring>\n");
     return -1;
            }
            int n = 0;
            int num = 0;
    int fd = open("gifts.dat", O_CREAT | O_WRONLY | O_RDONLY);
    if((strcmp(argv[1],"new"))==0){
            for(int i = 2; i < argc; i = i+2){
                    int number  = atoi(argv[i+1]);
                    strcpy(data, argv[i]);
                    int length = strlen(data) + 1;
                    write(fd,&length, sizeof(int));
                    write(fd,data, length);
                    write(fd,&number, sizeof(int));
            }
    }
    else{
            printf("Not worked");
    }
    for(int k =0;k < ((argc-2)/2);k++){
            int length;
            char*name = NULL;
            int money;
            read(fd, &length, sizeof(int));
            name = malloc(length);
            read(fd, name, length);
            read(fd, &money, sizeof(int));
            printf("%10s: %.2f\n", name, money);
            }
     return 0;

     }

然后这里是二进制文件的输出

gcc -o gifts board.c
./gifts new patel 200 Ram 500
      : 0.00
      : 0.00
od -c gifts.dat
0000000 006  \0  \0  \0   p   a   t   e   l  \0 310  \0  \0  \0 004  \0
0000020  \0  \0   R   a   m  \0 364 001  \0  \0  \0  \0
0000034
cat gifts.dat
patelÈRamô{cslinux1:~/CS3377_hmb180006}

确保在使用 gcc 编译之前使用alias gcc='gcc -std=c99'

【问题讨论】:

  • stackoverflow.com/help/minimal-reproducible-example 请发布文字而不是图片。当您的示例回复二进制文件时,您需要将其提供给我们以运行您的代码。
  • 我刚刚编辑了它。让我知道是否还有更多内容需要修改
  • 从实际检查每个 IO 调用的结果开始。目前没有个被验证,你盲目地假设它们都可以工作。您最多会发现第二个循环使用的文件描述符从未回绕,因此实际上没有什么可读取的。
  • @eliesmith read 返回一个值。应该检查一下。 write 返回一个值。应该检查一下。 open 返回一个值。应该检查一下。从字面上看,这段代码中的每一个系统调用都是未经检查的。注意Sixth Commandment of Henry Spencer。正如我之前所说,一旦你写完,描述符就会被定位在文件的end。你永远不会倒带文件。您希望阅读什么内容?
  • @WhozCraig - 谢谢。其他想法,int number = atoi("my cow"); 会很乐意将0 分配给number 而不会出错。

标签: c linux unix file-io binaryfiles


【解决方案1】:

主要问题在于您的open() 呼叫。您正试图同时以 只读只写 的形式打开该文件。来自ma​​n 2 open

参数标志必须包含一个以下访问权限 模式:O_RDONLYO_WRONLYO_RDWR

如下重构你的代码可以正常工作。

    char data[100];
    int fd = open ("gifts.dat", O_CREAT | O_WRONLY);
    int n = 0;
    
    if ((strcmp(argv[1],"new")) == 0) {
        for (int i = 2; i < argc; i = i+2){
            int number = atoi (argv[i+1]);
            strcpy (data, argv[i]);
            int length = strlen(data) + 1;
            write (fd, &length, sizeof(int));
            write (fd, data, length);
            write (fd, &number, sizeof(int));
            n++;
        }
    }
    else{
        printf("Not worked");
    }
    close (fd);
    fd = open ("gifts.dat", O_CREAT | O_RDONLY);
    
    for (int k = 0; k < n; k++){
        int length;
        char name[100];
        int money;
        
        read (fd, &length, sizeof(int));
        read (fd, name, length);
        read (fd, &money, sizeof(int));
        
        printf("%10s: %.2d\n", name, money);
    }
    close (fd);

使用/输出示例

$ ./bin/readwrite_bin new patel 200 Ram 500
     patel: 200
       Ram: 500

此外,您必须通过检查每个调用的返回来验证所有打开、读取、写入(和关闭 - 写入后)以确保成功,或者在失败时处理任何错误。您应该将atoi() 替换为至少sscanf() 或更好的strtol(),因为atoi() 提供零错误检测,并且很乐意接受atoi ("my cow");

如果您还有其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 2019-04-20
    • 2019-09-18
    • 2013-07-10
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2012-01-26
    相关资源
    最近更新 更多