c - getline 如何像使用 fgets 一样限制输入量
问题描述
此引用来自 GNU 手册
警告:如果输入数据有一个空字符,你无法分辨。因此,除非您知道数据不能包含空值,否则不要使用 fgets。不要使用它来读取用户编辑的文件,因为如果用户插入空字符,您应该正确处理它或打印明确的错误消息。我们建议使用 getline 而不是 fgets。
像往常一样,我在提问之前花时间搜索,我确实在五年前的 Stack Overflow 上发现了一个类似的问题: 为什么不推荐使用 fgets 函数?
尽管 GNU 建议使用getline
over fgets
,但我注意到getline
instdio.h
采用任何大小的行。它realloc
根据需要调用。如果我尝试将大小设置为 10 个字符:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buffer;
size_t bufsize = 10;
size_t characters;
buffer = (char *)malloc(bufsize * sizeof(char));
if( buffer == NULL)
{
perror("Unable to allocate buffer");
exit(1);
}
printf("Type something: ");
characters = getline(&buffer,&bufsize,stdin);
printf("%zu characters were read.\n",characters);
printf("You typed: '%s'\n",buffer);
return(0);
}
在上面的代码中,输入任意大小的字符串,超过 10 个字符,getline 将读取它并为您提供正确的输出。
甚至不需要malloc
,就像我在上面的代码中所做的那样——getline
为你做。我将缓冲区的大小设置为 0,并且会getline
根据需要为我设置。malloc
realloc
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buffer;
size_t bufsize = 0;
size_t characters;
printf("Type something: ");
characters = getline(&buffer,&bufsize,stdin);
printf("%zu characters were read.\n",characters);
printf("You typed: '%s'\n",buffer);
return(0);
}
如果您运行此代码,您可以再次输入任何大小的字符串,并且它可以工作。即使我将缓冲区大小设置为 0。
我一直在查看 CERT 指南www.securecoding.cert.org中的安全编码实践
我正在考虑从 切换fgets
到getline
,但我遇到的问题是我无法弄清楚如何限制getline
. 我认为恶意攻击者可以使用循环发送无限量的数据,并用尽堆中所有可用的内存?
getline
有没有办法限制在函数中使用或确实有一些限制的输入大小getline
?
解决方案
使用 fgets 不一定有问题,所有 gnu 手册都告诉您,如果文件中有 '\0'-Byte,那么缓冲区中也会有。您将无法判断缓冲区中的空分隔符是文件的实际结尾还是文件中的空值。这意味着您可以将 100 个字符的文件读入 200 个字符的缓冲区,它将包含一个 50 个字符的 c 字符串。
stdio.h readline 实际上似乎没有任何合理的长度限制,因此 fread 可能是可行的替代方案。
Unlinke C getline
and C++ std::getline()
, C++std::istream::getline()
仅限于count
字符
推荐阅读
- r - Shiny 应用程序中的 RSelenium:无法将 html 从浏览器中拉出
- python - 8 带爬山算法的女王不返回任何东西?
- coinbase-api - 如何在 Coinbase 上发送大于 1 美元的比特币?
- python-3.x - Python 'for loop' 不会导出所有记录
- python - 如何在 Kivy 应用程序中显示没有索引值和 [] 的 python 列表
- list - OctoberCMS - 如何在总计列的末尾添加新行?
- google-sheets - 计算有多少单元格包含 Google 表格中的特定字词
- mapbox - 关闭 Mapbox 上的动画
- html - 如何重新着色段落
- r - 即使在 Rstudio 中安装包后,Data.table 包也无法正常工作。如何修复?