fgets,其中读取的字符数大于存储大小
fgets where the number of char read is bigger than the size of the storage
我正在看一个代码来学习东西,我看到了这样的东西:
void funRead(){
char str[80];
FILE *fi;
fi = fopen("file","r");
while(!feof(fi)){
fgets(str, 200, fi);
// do things
}
fclose(fi);
}
而且有效! (这是一个相当大的代码)我不明白为什么它可以工作所以我试图重现它(只是这一部分,几乎只是上面的代码)并且我的程序崩溃了(我在 Eclipse).它只在我写
时有效
fgets(str, 80, fi);
或另一个<80的号码,否则将无法使用。
我是不是漏掉了什么?
EDIT :我正在谈论的程序部分的屏幕截图
https://gyazo.com/c8847ccc36bbbe7a406a3260db8dd358
第 4 和第 26 行
在您的代码中,您定义了一个大小为 80 个字符的字符数组
char str[80];
fgets(str, 200, fi);
上面的语句意味着它正在从字符数组“str”中的文件“fi”中读取200个字符" 大小 80。
您不能在大小为 80 的数组中复制 200 个字符。
要么扩大字符数组,要么一次从文件中读取 80 个或更少的字符。
编辑:程序崩溃的原因是因为它正在访问非法内存位置。这并不意味着如果你索引一个大于数组大小的位置它就会崩溃,它只是意味着如果不允许访问该内存位置它可能会崩溃。
这就是原因,您提到的代码可能有效(纯属偶然),尽管 200 部分是错误的。如果它 运行 然后 运行 它多次它可能至少会崩溃一次。
fgets(str, 200, fi);
确实是错误的,因为它是告诉fgets
往上读
到 199 个字符,而实际上 str
最多可以存储 79 个字符(不是
包括 '[=17=]'
终止字节),这就是为什么 "works"1 和 fgets(str, 80, fi);
.
一般来说,像这样使用 sizeof
是个好主意2:
char str[80];
fgets(str, sizeof str, fi);
使用 sizeof
您将获得正确的尺寸,即使您稍后决定更改
str
.
的大小
really wrong 的一件事是:
while(!feof(fi))
{
...
}
代码应该做的是:
while(fgets(str, sizeof str, fi))
{
// do things
}
这是读取整个文件的正确方法。
注释
1我把作品放在引号里是因为代码检查何时停止的方式
读数不正确。然而 fgets(str, 80, fi)
是正确的调用。
2请注意,只有当 str
是
大批。如果它是一个指针并且你为它分配了内存,那么你不能使用
sizeof
,例如:
size_t len = 80;
char *str = malloc(len);
if(str == NULL)
{
// error handling
}
fgets(str, len, fi); // <-- do not use sizeof here, but the variable
我正在看一个代码来学习东西,我看到了这样的东西:
void funRead(){
char str[80];
FILE *fi;
fi = fopen("file","r");
while(!feof(fi)){
fgets(str, 200, fi);
// do things
}
fclose(fi);
}
而且有效! (这是一个相当大的代码)我不明白为什么它可以工作所以我试图重现它(只是这一部分,几乎只是上面的代码)并且我的程序崩溃了(我在 Eclipse).它只在我写
时有效fgets(str, 80, fi);
或另一个<80的号码,否则将无法使用。
我是不是漏掉了什么?
EDIT :我正在谈论的程序部分的屏幕截图 https://gyazo.com/c8847ccc36bbbe7a406a3260db8dd358 第 4 和第 26 行
在您的代码中,您定义了一个大小为 80 个字符的字符数组
char str[80];
fgets(str, 200, fi);
上面的语句意味着它正在从字符数组“str”中的文件“fi”中读取200个字符" 大小 80。 您不能在大小为 80 的数组中复制 200 个字符。
要么扩大字符数组,要么一次从文件中读取 80 个或更少的字符。
编辑:程序崩溃的原因是因为它正在访问非法内存位置。这并不意味着如果你索引一个大于数组大小的位置它就会崩溃,它只是意味着如果不允许访问该内存位置它可能会崩溃。 这就是原因,您提到的代码可能有效(纯属偶然),尽管 200 部分是错误的。如果它 运行 然后 运行 它多次它可能至少会崩溃一次。
fgets(str, 200, fi);
确实是错误的,因为它是告诉fgets
往上读
到 199 个字符,而实际上 str
最多可以存储 79 个字符(不是
包括 '[=17=]'
终止字节),这就是为什么 "works"1 和 fgets(str, 80, fi);
.
一般来说,像这样使用 sizeof
是个好主意2:
char str[80];
fgets(str, sizeof str, fi);
使用 sizeof
您将获得正确的尺寸,即使您稍后决定更改
str
.
really wrong 的一件事是:
while(!feof(fi))
{
...
}
代码应该做的是:
while(fgets(str, sizeof str, fi))
{
// do things
}
这是读取整个文件的正确方法。
注释
1我把作品放在引号里是因为代码检查何时停止的方式
读数不正确。然而 fgets(str, 80, fi)
是正确的调用。
2请注意,只有当 str
是
大批。如果它是一个指针并且你为它分配了内存,那么你不能使用
sizeof
,例如:
size_t len = 80;
char *str = malloc(len);
if(str == NULL)
{
// error handling
}
fgets(str, len, fi); // <-- do not use sizeof here, but the variable