C程序设计中的结构
我试图读取一个文件的内容,并将其存储到一个结构中,因为某些原因,我不断遇到分段错误。请帮帮我,我也不太明白C程序设计中的结构,c,struct,C,Struct,我试图读取一个文件的内容,并将其存储到一个结构中,因为某些原因,我不断遇到分段错误。请帮帮我,我也不太明白 #include <stdio.h> #include <stdlib.h> typedef struct { int day; int month; int year; char text[401]; } journal; int main(int argc, char** argv){ int i, numberEn
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int day;
int month;
int year;
char text[401];
} journal;
int main(int argc, char** argv){
int i, numberEntries;
FILE* fp = fopen(argv[1], "r");
fscanf(fp,"%d", &numberEntries); /* reads value on first line of file for number of entries */
printf("%d", numberEntries); /* check that it worked */
journal *entryArray ;
entryArray = (journal*)malloc(sizeof(journal));
if(fp == NULL){
perror("Error opening file");
} else {
for(i=0; i<4; i++){
fscanf(fp,"%d/%d/%d", entryArray[i].day, entryArray[i].month, entryArray[i].year);
fgets(entryArray[i].text, 400, fp);
printf("%s", entryArray[i].text);
}
}
for(i=0; i<4; i++){
printf("%d %d %d", entryArray[i].day, entryArray[i].month, entryArray[i].year);
printf("%s", entryArray[i].text);
}
free(entryArray);
return 0;
}
至少有三个原因可能会导致程序中出现分段错误 首先,您在程序中进行了一次检查,以验证文件是否已成功打开。然而,您正在尝试在检查之前从文件中读取数据
fscanf(fp,"%d", &numberEntries);
如果文件未成功打开,fopen将返回空指针。试图通过空文件指针读取任何内容都会导致未定义的行为,这很容易表现为分段错误
typedef struct {
int day;
int month;
int year;
char text[401];
} journal;
int main(int argc, char** argv){
int i, numberEntries;
FILE* fp = fopen(argv[1], "r");
if(fp == NULL){
perror("Error opening file");
} else {
fscanf(fp,"%d", &numberEntries); /* reads value on first line of file for number of entries */
printf("%d", numberEntries); /* check that it worked */
journal *entryArray ;
entryArray = (journal*)malloc(numberEntries*sizeof(journal));
for(i=0; i<4; i++){
fscanf(fp,"%d/%d/%d", &entryArray[i].day, &entryArray[i].month, &entryArray[i].year);
fgets(entryArray[i].text, 400, fp);
printf("%s", entryArray[i].text);
}
for(i=0; i<4; i++){
printf("%d/%d/%d", entryArray[i].day, entryArray[i].month, entryArray[i].year);
printf("%s", entryArray[i].text);
}
free(entryArray);
}
return 0;
}
其次,entryArray总是只分配一个元素。然而,您正试图访问4个元素。这也很容易导致分割错误
顺便说一句,如果从文件中读取numberEntries,然后完全忽略该值,有什么意义
第三,具有%d格式的fscanf需要一个指向int的指针作为相应的变量参数。您提供了INT
这也会导致未定义的行为,通常伴随着分段错误。从您的第一个fscanf判断,您知道如何将%d与fscanf一起使用。你在第二次fscanf时忘记了吗
如果文件成功打开,那么99%的可能性是第三个问题导致代码中出现分段错误。这个问题在第二个问题之前就显露出来了
最后,输入数据的格式与硬编码到程序中的格式不匹配。由于在fscanf之后立即使用FGET,因此文本数据必须与日/月/年数据位于同一行。同时,在输入文件中,文本数据位于单独的一行。这肯定会破坏你的阅读代码
在读取日期之后和执行FGET之前,必须跳过行的其余部分和换行符。一种方法是在执行实际FGET之前执行假FGET
或者,您可以使用更复杂的fscanf格式,要求它使用并忽略换行符之前的所有内容,然后是换行符本身
for (i = 0; i<4; i++){
fscanf(fp, "%d/%d/%d%*[^\n]\n", &entryArray[i].day, &entryArray[i].month, &entryArray[i].year);
fgets(entryArray[i].text, 400, fp);
}
这些不是最好的方法,但只要输入文件坚持硬格式,它们就可以工作。分配一个日志entryArray=journal*mallocsizeofjournal;,然后将其视为数组fgetsentryArray[i]
这是行不通的…使用GDB获取代码中的segfault偏移量。根据具体情况,SEGFULT可能发生在任何地方。所以在这方面很难帮到你。嘿,我已经根据你的观点更新了代码,但出于某种原因,它显示较低的for循环entryArray在终端中未声明,你知道为什么会发生这种情况吗?谢谢。@IamTrent:在块{…}中声明的变量只存在于该块的末尾。它不存在于那个街区之外。您不能在else{…}块之外访问entryArray。应该是这样的。既然你把几乎所有的东西都放进了else分支,那么就把剩下的代码也放进去吧。好吧,我更新了代码,仍然得到了segfaults,还有其他想法吗?谢谢。@IamTrent:嗯,我试过运行你的最新版本,它对我来说运行得非常好。当然,我必须根据我可以从您的代码中逆向工程的格式创建一个假输入文件。我没有你的输入数据。您实际文件的格式可能与您在代码中编写的格式不匹配。如果问题中的输入文件太大,请发布输入文件或其中的一部分。
fscanf(fp,"%d/%d/%d", entryArray[i].day, entryArray[i].month, entryArray[i].year);
for(i=0; i<4; i++){
fscanf(fp,"%d/%d/%d", &entryArray[i].day, &entryArray[i].month, &entryArray[i].year);
fgets(entryArray[i].text, 400, fp); // <- fake `fgets`
fgets(entryArray[i].text, 400, fp);
}
for(i=0; i<4; i++){
fscanf(fp,"%d/%d/%d ", &entryArray[i].day, &entryArray[i].month, &entryArray[i].year);
fgets(entryArray[i].text, 400, fp);
}
for (i = 0; i<4; i++){
fscanf(fp, "%d/%d/%d%*[^\n]\n", &entryArray[i].day, &entryArray[i].month, &entryArray[i].year);
fgets(entryArray[i].text, 400, fp);
}