我正在尝试读取文件内容并将其存储到结构中,因为某些原因我不断收到分段错误.请帮助我,我也不了解valgrind.
#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;
}
Run Code Online (Sandbox Code Playgroud)
更新的代码:仍然给出了分段错误.
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;
}
Run Code Online (Sandbox Code Playgroud)
输入文件
4
12/04/2010
Interview went well I think, though was told to wear shoes.
18/04/2010
Doc advised me to concentrate on something... I forget.
03/05/2010
Was asked today if I was an art exhibit.
19/05/2010
Apparently mudcakes not made of mud, or angry wasps.
Run Code Online (Sandbox Code Playgroud)
至少有三个原因可能(并且将会)导致程序中的分段错误
首先,您检查程序是否验证文件是否已成功打开.但是,您在检查之前尝试从文件中读取数据
fscanf(fp,"%d", &numberEntries);
Run Code Online (Sandbox Code Playgroud)
如果文件未成功打开,则fopen返回空指针.尝试通过空文件指针读取任何内容会导致未定义的行为,这可能很容易表现为分段错误.
其次,entryArray总是只分配一个元素.然而,您正在尝试访问4个元素.这可能(并且将会)容易导致分段错误.
顺便说一下,如果numberEntries从文件中读取然后完全忽略该值,那又有什么意义呢?
第三,fscanf与%d格式需要一个指针到int作为对应的可变参数的参数.你已经提供了ints
fscanf(fp,"%d/%d/%d", entryArray[i].day, entryArray[i].month, entryArray[i].year);
Run Code Online (Sandbox Code Playgroud)
这也会导致通常伴随分段错误的未定义行为.通过你的第一个判断fscanf,你知道如何使用%d带fscanf.你第二次忘记了fscanf吗?
如果文件成功打开,则有99%的可能性是导致代码中出现分段错误的第三个问题.在第二个问题出现之前,这个问
最后,输入数据的格式与您硬编码到程序中的格式不匹配.由于您fgets之后立即使用fscanf,因此text数据必须与数据位于同一行day/month/year.同时,在输入文件中,text数据位于单独的行中.这肯定会破坏你的阅读代码.
在阅读日期之后和之前,您必须跳过行的其余部分和换行符fgets.一种方法是fgets在做实际之前执行"假"fgets
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);
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以将尾随空格字符添加到fscanf格式中以强制fscanf使用所有尾随空格
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);
}
Run Code Online (Sandbox Code Playgroud)
或者您可以使用更复杂的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);
}
Run Code Online (Sandbox Code Playgroud)
这些并不是最好的方法,但只要输入文件符合硬格式,它们就能正常工作.