使用 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 时防止缓冲区溢出的主要内容,如果未能解决你的问题,请参考以下文章