使用 fscanf 时防止缓冲区溢出

Posted

技术标签:

【中文标题】使用 fscanf 时防止缓冲区溢出【英文标题】:Preventing buffer overflow when using fscanf 【发布时间】:2013-09-17 08:47:33 【问题描述】:

我正在使用 fscanf 从 CSV 文件中读取一些值,我想确保读取到这些值中的数据不会太大而导致缓冲区溢出。

我的 csv 文件具有 int,string,string 格式,我要读取的代码如下(稍后我将修复 while 条件):

while(fscanf(f, "%d,%[^,],%[^,]", &inArray[i].ID, inArray[i].label, inArray[i].brand)/*insert while condition here*/

使用 scanf 时,我会像这样指定长度以防止溢出:scanf("%20f", example);

但如果我尝试与上述相同:while(fscanf(f, "%d,%20[^,],%10[^,]", &inArray[i].ID, inArray[i].label, inArray[i].brand)/*insert while condition here*/

代码执行时发生崩溃。

【问题讨论】:

你试过调试吗?它在循环的第一次迭代中崩溃了吗?你如何初始化i 如果你想学习 C++ 读取格式化输入的方法,你可能想看看cppreference on istream operator >> 【参考方案1】:

试试fscanf_s,这个功能增强了安全性。 http://msdn.microsoft.com/en-us/library/6ybhk9kc(v=vs.90).aspx

【讨论】:

显然,fscanf_s 看起来是一个糟糕的解决方案。 ***.com/a/6153517/23118【参考方案2】:

在读取字符时,你不能用 fprintf 做到这一点。

我会首先阅读整行,例如,使用getline(),找到分隔符(或标记该行),然后解析各个元素。

顺便说一句,您崩溃的原因也可能是 inArray 的错误定义/初始化。

【讨论】:

【参考方案3】:

OP 可能在 fscanf() 中使用了错误的宽度。

虽然 OP 没有发布有关 inArray[i] 的详细信息,但我们假设它是

struct 
  int ID;
  char label[20];
  char brand[10];
 inArray[100];

格式应该是

"%d,%19[^,],%9[^,]"

19 的宽度需要比目标的大小小 1,从而为 '\0' 留出一个位置。

【讨论】:

以上是关于使用 fscanf 时防止缓冲区溢出的主要内容,如果未能解决你的问题,请参考以下文章

C语言:防止缓冲区溢出

C语言:防止缓冲区溢出

怎么解决 LINUX 堆栈溢出内存的问题

缓冲区溢出攻击实践

如何处理Android中的防缓冲区溢出技术

C语言中为了避免缓冲区溢出应尽量使用哪些函数