程序要求用户输入并将其写入.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);
}
}
答案 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]));
对所有其他领域也这样做。
您将编写每个数组的完整大小,无论是否有有用的数据,但是没关系。您只需以类似的方式读取整个数组。此外,由于每个元素都是固定大小,因此可以更轻松地跳转到特定记录。如果记录在数据文件中是可变大小的话,你将无法做到这一点。