C 为什么从文件读取函数会崩溃?

C 为什么从文件读取函数会崩溃?,c,file,fgets,strcpy,C,File,Fgets,Strcpy,试图从文件中读取多行以将它们存储在由字符串元素组成的结构中,但当我运行程序时,它只是崩溃了,我一点也不知道为什么 有关职能: Hashtbl* loadfromfile(Hashtbl* hashtbl, char *path){ int i = 0; char line[100]; char* string[40]; FILE *f = fopen(path, "r"); if(f == NULL){ printf("FILE NO

试图从文件中读取多行以将它们存储在由字符串元素组成的结构中,但当我运行程序时,它只是崩溃了,我一点也不知道为什么

有关职能:

Hashtbl* loadfromfile(Hashtbl* hashtbl, char *path){
    int i = 0;
    char line[100];
    char* string[40];

    FILE *f = fopen(path, "r");

    if(f == NULL){
        printf("FILE NO FOUND!");
    }else{
        while(fgets(line, sizeof(line), f)!=NULL){
           strcpy(string[i],line);
           i++;
       }
       fclose(f);
       for(i = 0; i<(SIZE*2); i++){
            strcpy(hashtbl[i].subscript, string[i]);
            i++;
       }

       for(i = 1; i<(SIZE*2); i++){
           strcpy(hashtbl[i].value, string[i]);
           i++;
       }

       return hashtbl;
       }
}
init_hasthable函数:

   Hashtbl* init_hashtbl(){
       Hashtbl* hashtbl;
       hashtbl = calloc(SIZE, sizeof(Hashtbl));
       for(int i = 0; i<SIZE; i++){
           hashtbl[i].subscript = "ZERO";
           hashtbl[i].value = "ZERO";
       }
       return hashtbl;
   }
Hashtbl*init_Hashtbl(){
Hashtbl*Hashtbl;
hashtbl=calloc(SIZE,sizeof(hashtbl));

对于(int i=0;i您在这里遇到了很多问题:

if(f == NULL){
    printf("FILE NO FOUND!");
}
如果无法打开该文件,则无法继续。此外,该消息可能会丢失 如果以后要打印,请改用
printf(“未找到文件!\n”);

char* string[40];
...
while(fgets(line, sizeof(line), f)!=NULL){
    strcpy(string[i],line);
    i++;
}
string
是一个未初始化指针数组,不能写入任何内容 好了,你应该这样做

while(fgets(line, sizeof line, f))
{
    string[i] = malloc(strlen(line) + 1);
    if(string[i] == NULL)
    {
        // error handling is needed
    }
    strcpy(string[i], line);
    i++;
    if(i == sizeof string / sizeof *string)
        break;
}

// or if your system has strdup

while(fgets(line, sizeof line, f))
{
    string[i] = strdup(line);
    if(string[i] == NULL)
    {
        // error handling is needed
    }
    i++;
    if(i == sizeof string / sizeof *string)
        break;
}
你也没有检查你是否读了超过40行,我是用 最后一个
if
sizeof array/sizeof*array
返回 数组可以容纳的元素。请注意,这仅适用于数组,而不适用于 指针,因为在一般情况下,
sizeof数组!=sizeof指针
。也不要忘记 之后释放分配的内存

strcpy(hashtbl[i].subscript, string[i]);
...
strcpy(hashtbl[i].value, string[i]);
此处的
下标
参数是否以某种方式初始化?检查 您的
init\u hashtbl()


编辑

现在您发布了
init\u hashtbl

for(i = 0; i<(SIZE*2); i++){
    strcpy(hashtbl[i].subscript, string[i]);
    i++;
}
您应该始终检查
malloc
/
calloc
的返回值 这里的问题是,如果要复制长度超过
如果某个最大长度
,您将出现缓冲区溢出。因此您应该
在读取例程中使用realloc:

for(i = 0; i<(SIZE*2); i++){
    char *tmp = realloc(hashtbl[i].subscript, strlen(string[i]) + 1);
    if(tmp == NULL)
    {
        // error handling
    }

    hashtbl[i].subscript = tmp;
    strcpy(hashtbl[i].subscript, string[i]);
    i++;
}
然后在
loadfromfile
中,您不必处理
realloc
,如图所示 您可以保留您的代码。但是,您必须检查是否没有
string[i]
大于某个\u最大\u长度-1
,否则缓冲区溢出

最后一件事,
fgets
读取整行,假设 行小于行的大小,换行符将添加到 线。你很可能不想这样。一种摆脱线的方法 新行是:

fgets(line, sizeof line, f);
int len = strlen(line);
if(line[len - 1] == '\n')
    line[len - 1] = 0;

您在这里遇到了很多问题:

if(f == NULL){
    printf("FILE NO FOUND!");
}
如果无法打开该文件,则无法继续。此外,该消息可能会丢失 如果以后要打印,请改用
printf(“未找到文件!\n”);

char* string[40];
...
while(fgets(line, sizeof(line), f)!=NULL){
    strcpy(string[i],line);
    i++;
}
string
是一个未初始化指针数组,不能写入任何内容 好了,你应该这样做

while(fgets(line, sizeof line, f))
{
    string[i] = malloc(strlen(line) + 1);
    if(string[i] == NULL)
    {
        // error handling is needed
    }
    strcpy(string[i], line);
    i++;
    if(i == sizeof string / sizeof *string)
        break;
}

// or if your system has strdup

while(fgets(line, sizeof line, f))
{
    string[i] = strdup(line);
    if(string[i] == NULL)
    {
        // error handling is needed
    }
    i++;
    if(i == sizeof string / sizeof *string)
        break;
}
你也没有检查你是否读了超过40行,我是用 最后一个
if
sizeof array/sizeof*array
返回 数组可以容纳的元素。请注意,这仅适用于数组,而不适用于 指针,因为在一般情况下,
sizeof数组!=sizeof指针
。也不要忘记 之后释放分配的内存

strcpy(hashtbl[i].subscript, string[i]);
...
strcpy(hashtbl[i].value, string[i]);
此处的
下标
参数是否以某种方式初始化?检查 您的
init\u hashtbl()


编辑

现在您发布了
init\u hashtbl

for(i = 0; i<(SIZE*2); i++){
    strcpy(hashtbl[i].subscript, string[i]);
    i++;
}
您应该始终检查
malloc
/
calloc
的返回值 这里的问题是,如果要复制长度超过
如果某个最大长度
,您将出现缓冲区溢出。因此您应该
在读取例程中使用realloc:

for(i = 0; i<(SIZE*2); i++){
    char *tmp = realloc(hashtbl[i].subscript, strlen(string[i]) + 1);
    if(tmp == NULL)
    {
        // error handling
    }

    hashtbl[i].subscript = tmp;
    strcpy(hashtbl[i].subscript, string[i]);
    i++;
}
然后在
loadfromfile
中,您不必处理
realloc
,如图所示 您可以保留您的代码。但是,您必须检查是否没有
string[i]
大于某个\u最大\u长度-1
,否则缓冲区溢出

最后一件事,
fgets
读取整行,假设 行小于行的大小,换行符将添加到 线。你很可能不想这样。一种摆脱线的方法 新行是:

fgets(line, sizeof line, f);
int len = strlen(line);
if(line[len - 1] == '\n')
    line[len - 1] = 0;

如果(f==NULL){printf(“找不到文件!”);}
为什么继续?此时应停止处理strcpy(字符串[i],行)
-您尚未为此分配空间显示
init_hashtbl
Hashtbls.subscript
Hashtbls.value
可能未初始化。而且
char*string[40];
未初始化,因此
strcpy(string[i],line);
正在尝试通过指向任何地方的指针进行写入。
while(fgets)(line,sizeof(line,f)!=NULL){
->应该检查我是否在40岁以下?如果你想成为一名开发人员,你必须学会调试你的代码。把你带到调试器-去!
如果(f==NULL){printf(“找不到文件!”);}
-为什么继续?你应该在这一点停止处理
strcpy(string[i],line);
-您尚未为此分配空间,请显示
init_hashtbl
Hashtbls.subscript
Hashtbls.value
可能未初始化。此外,
char*string[40];
未初始化,因此
strcpy(string[i],line);
正在尝试通过指向任何地方的指针进行写入。
while(fgets)(行,sizeof(行,f)!=NULL){
->应该检查我是否在40岁以下?如果你想成为一名开发人员,你必须学会调试你的代码。让你去调试器-去!非常好的努力和非常好的捕获来解释从
修剪尾部
'\n'
。错误消息应该打印在
stderr
上,而不是
stdout
。这就是它的目的。非常有魅力地工作。谢谢,特别感谢你花时间如此彻底地解释了一切。非常好的努力和非常好的收获解释了从
修剪尾部
。\n'
。错误消息应该打印在
标准字符上,而不是
标准字符上。这就是它的目的谢谢,特别是感谢你花时间解释我的一切