我正在尝试用C编写一个程序,该程序从输入文件("input0")中读取,格式如下:John Doe 1230 4.0
我正在尝试使用fscanf读取文档,并将这些值输入到结构中。然而,目前,在编译并运行代码后,我遇到了神秘的"分段故障(核心转储)">
我的代码中当前发出此错误的行是带有fscanf语句的行。我找不到解决这个问题的办法。
此外,strcpy在取消注释后会给出一个错误。当我运行代码时,我收到了一个警告,我认为这一定是指针和字符串不一致,这是我无法解决的另一个问题。如有任何帮助,我们将不胜感激。
typedef struct {
char fname[1000];
char lname[1000];
long int id;
double gpa;
} student_t;
int main(int argc, char *argv[]) {
FILE *db;
student_t students[1000];
char* fname[1000];
char* lname[1000];
long int id[1000];
double gpa[1000];
long int i, j;
i = 0;
db = fopen("input0", "r");
while(fscanf(db, "%s %s %d %lf", fname[i], lname[i], id[i], gpa[i]) != EOF) {
//strcpy(students[i].fname, fname[i]);
//strcpy(students[i].lname, lname[i]);
students[i].id = id[i];
students[i].gpa = gpa[i];
i++;
}
for(j = 0; j <= i; j++) {
//printf("%s %s %d %fn", _SJ.fname, _SJ.lname, _SJ.id, _ST.gpa);
}
fclose(db);
}
当您声明例如时
char* fname[1000];
您有一个未初始化的1000
指针数组。尝试使用其中一个指针将导致未定义的行为。您需要为指针分配内存,或者将它们指向其他(已分配的)内存。
事实上,我认为你真正想做的是
fscanf(db, "%s %s %d %lf",
students[i].fname, students[i].lname, &students[i].id, &students[i].gpa)
我还建议您阅读例如这个fscanf
引用,因为fscanf
可以返回其他值,这意味着输入中存在错误(例如,如果输入文件格式错误)。
您忘记将&
用于fscanf
中的long int
和double
while(fscanf(db, "%s %s %d %lf", fname[i], lname[i], &id[i], &gpa[i]) != EOF)
更改此行
while(fscanf(db, "%s %s %d %lf", fname[i], lname[i], id[i], gpa[i]) != EOF)
至
while(fscanf(db, "%s %s %d %lf", students[i].fname, students[i].lname, &students[i].id, &students[i].gpa) != EOF)
那么您可能不需要任何strcpy
,也不需要将int
和double
复制回结构中。
char *fname[1000]
将分配char
的1000个指针
我修复了一些问题:
typedef struct {
char fname[1000];
char lname[1000];
long int id;
double gpa;
} student_t;
student_t students[1000];
int main(int argc, char *argv[]) {
FILE *db;
long int i=0, j;
db = fopen("input0.txt", "r");
if (db == NULL)
{
perror("Error opening file input0");
return -1;
}
while (fscanf(db, "%s %s %d %lf", students[i].fname, students[i].lname,
&students[i].id, &students[i].gpa) != EOF)
{
i++;
}
for (j = 0; j < i; j++) {
printf("%s %s %d %fn", students[j].fname, students[j].lname, students[j].id, students[j].gpa);
}
fclose(db);
}
你可以直接读取学生数组,避免了玩strcpy。失踪的&也添加了。请注意,我将student[1000]移到了主函数之外,因为VS2013的标准堆栈大小导致代码产生堆栈溢出。打开文件时,请始终检查是否成功打开了它们。。。这将在将来节省许多小时的调试痛苦。j<i条件已更改为j
在您的原始代码中:
char* fname[1000];
您使用了1000 char*,但这一行只为指针本身分配了空间。我想你想写这样的东西:
char fname[1000];
在这种情况下,框架将有1000个字符,可以用来存储从输入文件读取的名称。在进一步研究C之前,注意这两行之间的差异是非常重要的。在fname[1000]的情况下,你可以读到fname,即没有索引。然后是strcpy(学生[i].fname,fname)。我希望它能有所帮助。