回答
char * fgets (char * str, int num, FILE * stream);
可以安全使用,因为它避免了buffer overflow问题,它只扫描num-1
个字符。
从流中读取字符并将它们作为C字符串存储到str中,直到读取了(num-1)个字符或达到换行符或文件结束时,以先发生者为准。
这里第二个参数num
是要复制到str的最大字符数(包括终止空字符)。
例如,假设在您的代码中字符串数组容量仅为5
字符,如下所示。
char str[5];
fgets (str, 5, fp); //5 =you have provision to avoid buffer overrun
使用上述代码中,如果从fp
输入端较长然后4
字符,fgets()
将读取只是第一4
字符然后追加\0
(,并丢弃其它额外输入字符,只是存储5个炭在str[]
)。
而scanf(" %[^\n]",str);
将读到\n
没有发现,如果输入的字符串长度超过4
字符scanf()
会造成buffer overflow(如scanf
将尝试在str[]
访问内存超出最大指数4
)。
感谢您的详细解释。如果我不知道输入字符串有多长时间,scanf()会是更好的选择吗? – amulous
@ amulous:YuHao先生给了一个很好的链接。在那里阅读,'scanf()','printf()'系列函数适用于格式化输入/输出 –
简单的说:是的,fgets
是更好的选择。
我看着你的scanf
格式说明符,我很困惑。完全理解它的功能需要一些时间阅读man
页面。
此外,您的scanf
代码易受缓冲区溢出的影响。
保持简单,您将降低维护成本并避免难以发现错误!
缓冲区溢出是恶魔。得到它了。谢谢。 – amulous
fgets
会比这更好scanf
。 可以有以下与scanf
问题如OP
1)缓冲区泄出鉴于@Grijesh
所建议2)可能下一个scanf
后,因为换行输入流中离开这将无法工作。 (如果你错过了空格)
是fgets是从标准输入中读取一行的更好和安全的方式。
此外,在代码中会有更多的可读性。看看你给出的scanf语句。
任何第二个看到它的人都会感到困惑。但是,fgets会有更多的可能性,这很容易理解。
你反驳了你自己。也许你的意思是在你的第一句话中“fgets”。 –
@Jim Balter谢谢你的纠正 –
不用fgets(...)而使用下面的代码片断:
char _x[7000];
char* y;
while (! feof (_f))
{
fscanf(_f,"%[^\n]\n",_x);
y=x;
}
- 1. 如何使用scanf \ fscanf读取一行并解析变量?
- 2. scanf()读取减号并不放回
- 3. 使用scanf读取unsigned char
- 4. 从scanf读取换行
- 5. 如何使用scanf以空格读取文件的每一行?
- 6. 用scanf读取多行输入
- 7. 使用scanf读取小int int
- 8. 检测使用scanf读取非数字()
- 9. 如何使用scanf读取空格?
- 10. 使用scanf从stdin C读取文件
- 11. 使用scanf挂起的输入读取
- 12. 使用scanf的读取字符串,并通过/
- 13. 读取行,并使用LINQ
- 14. SCANF行为读取时焦炭
- 15. 使用scanf并同时获取
- 16. 通读流读取器并使用行
- 17. SCANF不读输入
- 18. scanf的好奇行为
- 19. scanf()好奇的行为!
- 20. Scanf不能读取双精度值
- 21. 使用scanf在C中读取一定数量的字符?
- 22. 使用Scanf读取一个随机长度公式
- 23. scanf读取超过要求
- 24. Scanf()不读取数字0或读取错误
- 25. 如何通过cstdio :: scanf在一行中读取三个整数?
- 26. 读取数据并用scanf跳过括号
- 27. 如何用scanf读取空格
- 28. 如何通过scanf读取文件中的不同行输入
- 29. 使用scanf()读取for循环中使用的整数
- 30. 使用Go并行读取多个URL
应当SCANF( “%[^ \ n]的”,线);关闭大括号中的参数.. –
他绝对是。我总是建议使用'fgets()'并完全避免'scanf()'。 – 2013-06-25 10:27:50
@RaghuSrikanthReddy为什么不使用'scanf()'的完美例子。 – 2013-06-25 10:28:07