C程序读写二进制文件

问题描述

您好,这是我第一次使用 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,sizeof(int));
            name = malloc(length);
            read(fd,name,length);
            read(fd,&money,sizeof(int));
            printf("%10s: %.2f\n",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'

解决方法

主要问题在于您的 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,sizeof(int));
        read (fd,name,length);
        read (fd,&money,sizeof(int));
        
        printf("%10s: %.2d\n",money);
    }
    close (fd);

示例使用/输出

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

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

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