在C

时间:2015-09-15 17:16:35

标签: c file

程序要求用户输入并将其写入.dat文件。输入是指定数量学生的姓名,身份证,出生日期,性别和婚姻状况。必须将数据作为单独的字段写入文件,以便以后可以从文件中读取数据。

说这是来自终端的输入:

对于学生1 输入姓名:John Doe
输入ID:1234
输入出生日期:01/01/90
输入性别:男
输入婚姻状况:单身

对于学生2 输入姓名:Jane Smith
输入ID:5678
输入出生日期:09/08/92
输入性别:女为 输入婚姻状况:单身

这是文件中的输出。

John Doe \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 0012 \ 001234 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ _ 0001/01/90 \ 00 \ C2Male \ 00Single \ 00 \ FF \ FF \ FFJane Smith \ 00 \ C2 \ FF \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 005678 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 0009/08/92 \ 00Female \ 00Single \ 00 \ C2 \ FF

我想像\ 00等字符出现是因为,对于每个数组元素,我写的文件比文件元素包含的字节多;但是我需要文件中的每个数据都是固定大小的,以便以后可以从文件中单独读取,对吧?我该怎么办呢?

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(){
    int fd, i = 0;
    char name[2][20], id[2][10], dob[2][10], gender[2][7], status[2][10];
    fd = open("file.dat", O_WRONLY|O_CREAT); //open file.dat for writing; if it does not exist, create it.
    //get input from user
    for (i = 0; i < 2; i++){
        printf("\nFor student %d\n", (i + 1));
        printf("Enter name: ");
        scanf("%[^\n]%*c", &name[i][20]); //%[^\n]%*c - read everything up to (excluding) new line character
        printf("Enter ID: ");
        scanf("%s", &id[i][10]);
        printf("Enter date of birth: ");
        scanf("%s", &dob[i][10]);
        printf("Enter gender: ");
        scanf("%s", &gender[i][7]);
        printf("Enter marital status: ");
        scanf("%s", &status[i][10]);
        getchar();
    }

    for (i = 0; i < 2; i ++){
        write(fd, (void*)&name[i][20], 20);
        write(fd, (void*)&id[i][10], 10);
        write(fd, (void*)&dob[i][10], 10);
        write(fd, (void*)&gender[i][7], 7);
        write(fd, (void*)&status[i][10], 10);
    }
}

3 个答案:

答案 0 :(得分:1)

 scanf("%s", &id[i][10]); //you want to store string but id[i][10] can store single char at index [i][10].

此声明应为 -

 scanf("%9s",id[i]);

Similare这些scanf

                                   // CORRECTIONS 
 scanf("%[^\n]%*c", &name[i][20])  //->   scanf("%19[^\n]%*c",name[i])
 ...
 scanf("%s", &dob[i][10]);         //->   scanf("%9s", dob[i]);
 ...
 scanf("%s", &gender[i][7]);       // ->  scanf("%6s", gender[i]); 
 ...
 scanf("%s", &status[i][10]);      //->   scanf("%9s", status[i]);

write语句应该是这样的 -

write(fd, (void*)&id[i][10], 10);   //-> write(fd,id[i],sizeof id[i]);

与其他陈述类似。

答案 1 :(得分:1)

为什么不写出'\ n'或任何其他分隔符终止的每个数据的确切长度,当您必须读取所有文件时读取所有文件,然后将读取的数据拆分为所选分隔符,或者你每次阅读分隔符时拆分它吗?

你不会知道要阅读的确切长度,但你不会有不想要的角色。您只需要循环读取,直到到达文件末尾。

答案 2 :(得分:0)

您没有正确阅读和撰写字段。

例如,当您在name中阅读时

scanf("%[^\n]%*c", &name[i][20]);

您实际上是在一个字符的地址中传递了数组中的最后一个字符,而不是第一个字符的地址。这就是这样做的:

scanf("%[^\n]%*c", name[i]);

同样适用于write电话:

write(fd, (void*)&name[i][20], 20);

您想传入数组第一个字符的地址。此外,您使用sizeof运算符传递每个数组的大小而不是使用数字文字:

write(fd, name[i], sizeof(name[i]));

对所有其他领域也这样做。

您将编写每个数组的完整大小,无论是否有有用的数据,但是没关系。您只需以类似的方式读取整个数组。此外,由于每个元素都是固定大小,因此可以更轻松地跳转到特定记录。如果记录在数据文件中是可变大小的话,你将无法做到这一点。