我需要读入一个文件,然后将每个结构大小的字符分配给结构数组的一部分。
因此,前 30 个字符将是第一个,第二个 30 个字符将是最后一个,之后的 9 个字符将是 ssn。这将是阵列中的第一个学生。第二个学生将在第 69 个字符之后开始,第三个学生将在第 138 个字符之后开始,依此类推。
在该文件中,会有以下内容: 约翰\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0史密斯\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0123456789 jack \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0迈尔斯\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0987654321
这将转换为:
allStudents[0].first = 约翰
allStudents[0].last = 史密斯
所有学生[0].ssn = 123456789
allStudents[1].first = jack
allStudents[1].last = 迈尔斯
所有学生[1].ssn = 987654321
这是当前设置:
struct student allStudents[1000];
struct student {
char first[30];
char last[30];
char ssn[9];
};
void findStudents() {
int i;
FILE *fp;
char *temp;
int counter = 0;
int counter2 = 0;
fp = fopen("students.db","rt");
while( ( temp[counter2] = fgetc(fp) ) != EOF )
{
for (i = 0 ; i < 30 ; i++) {
strcat(allStudents[counter].first, temp);
counter2++;
}
for (i = 0 ; i < 30 ; i++) {
strcat(allStudents[counter].last, temp);
counter2++;
}
for (i = 0 ; i < 9 ; i++) {
strcat(allStudents[counter].ssn, temp);
counter2++;
}
counter++;
}
fclose(fp);
}
最佳答案
正如评论中提到的,这里存在多个问题,从没有为 char *temp
分配内存到使用长度为 9 的 char 数组来存储 9 个字符长的数字,没有空间终止性格。
尝试进行尽可能少的更改,我会将结构中的 ssn
大小从 9 更改为 10,以便存储终止字符。请记住,您可以使用整数来存储该数据,这在内存存储方面会更有效。
我想指出的另一件事是您的 struct Student allStudents[1000]
数组。即使数据库中只有 2 条记录,您也会立即分配 1000 * sizeof(struct)
字节。也许更好的方法是使用链表。或者只是拥有一个结构体指针数组(struct Student *allStudents[1000]
),这最初会占用更少的内存,但您必须为每个新结构体分配内存。
我假设您不允许更改 students.db
文件,但我们仍然需要添加该终止字符,因此文件中的单个记录将有 69 个字节,70 个字节结构中的字节。如果允许的话,我建议你改一下。
struct student {
// max allowed first and last name length should be 29 to ensure a space for terminating character
char first[30];
char last[30];
char ssn[10];
}
struct student allStudents[1000];
void findStudents() {
int counter = 0;
// if you want to just read the file use "r" mode, if you're writing in it you can use "r+" or "w+", but there is no "rt" as far as I know
FILE *fp = fopen("students.db", "r");
// you should always check if file is opened
if(fp == NULL) {
printf("File not opened");
return;
}
// allocate memory where you will store a single record read from a file
// note -1 since your struct is now 70bytes large and a record in file is 69
// and for that reason we are using calloc instead of malloc, since calloc fills allocated memory with zero
char *temp = (char*) calloc(1, sizeof(struct student) - 1);
// instead of using fgetc for reading a single character, it's better to use fread here
// fread returns number of elements successfully read which should be 69 if everything is alright
while( ( fread(temp, 1, sizeof(struct student) - 1, fp) ) == sizeof(struct student) - 1 ) {
// copy the content we read into the structure
// we copy only 69 bytes here, leaving the last byte of structure untouched
// and it will be 0x00 (terminating character for your ssn)
memcpy(&allStudents[counter], temp, sizeof(struct student) - 1);
counter++;
}
// free the allocated memory and close the file since you won't be using them anymore
free(temp);
fclose(fp);
}
我还建议您也许返回从 student.db
数据库中读取的条目数。
我编写此代码的假设是您无法更改 student.db
的文件结构,但如果允许,请考虑上述建议。
关于c - 如何读入文件,然后将文件中的每个结构放入数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56075743/