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'
。错误消息应该打印在标准字符上,而不是标准字符上。这就是它的目的谢谢,特别是感谢你花时间解释我的一切