2015-09-15 29 views
1

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

之所以这样说,是从终端输入:

学生1
输入姓名:李四
输入ID:1234
输入出生日期:90年1月1日
输入性别:男
填写婚姻状况:未婚

学生2
输入名称:珍妮·史密斯
输入ID:5678
输入出生日期:92年9月8日
输入性别:女
填写婚姻状况:未婚

这是文件中的输出。

John Doe \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 00 \ 0\ 00 \ 00 \ 00 \ 00 \ 00 \ 0001/01/90 \ 00 \ C2Male \ 00Single \ 00 \ FF \ FF \ FFJane Smith \ 00 \ C2 \ FF \ 00 \ 00 \ 00 \ 00 \ 00 \ 005678 \ 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); 
    } 
} 
+2

你应该写'strlen(&name [i] [20])'字节而不是固定值。 '20'应该可能是'0'。 – arrowd

+1

你不清楚该文件将会是什么格式。向你自己描述你想要什么内容(以及如何阅读它),然后你可以制定出如何编写它 – pm100

回答

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

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

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

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])); 

执行相同的所有其他领域。

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