gets,fgets,scanf与字符串的故事

本文介绍了C语言中替代gets函数的fgets和scanf函数。详细讲解了fgets的函数原型和工作原理,以及如何使用scanf输入字符串,包括扫描集的概念和使用示例,展示了如何处理带有空格的字符串输入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.gets

gets是从标准输入设备读取字符串的函数,函数原型 char * gets ( char * str );  刚开始学习C语言时觉得gets这个函数相当的好用,因为他比scanf写起来要短,而且可以输入有空格的字符串。但是越往后学就会发现,在C语言中用GCC编译使用了gets函数的源文件,编译器会给警告。

warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]

警告: the `gets' function is dangerous and should not be used.

 

原因是gets可以无限读取,不会判断上限,如果无限输入会造成栈空间溢出,在程序返回时,不能正常的找到返回地址,程序将发生不可预测行为。如果用了gets,像我们现在写的小程序可能在PC端上会闪退,但如果在大型项目中就会造成很严重的损失。因此我们应该尽量避免使用gets函数,顺便一提在2011年12月,ANSI 采纳了 ISO/IEC 9899:2011 标准,标准中删除了 gets()函数,使用一个新的更安全的函数gets_s()替代。

如果不用gets想要输入字符串,就要用到fgets和scanf了

2.fgets

        函数原型char *fgets(char *buf, i

<think>嗯,用户问的是getsscanf字符串输入上的区别。首先我得回忆一下这两个函数的基本用法,然后找出它们的不同点。可能涉及到缓冲区溢出、处理空格的方式、返回值这些方面。 首先,scanf在读取字符串时,遇到空格、制表符或换行符会停止,而gets会一直读取直到遇到换行符或者文件结束。这意味着scanf不能读取包含空格的字符串,而gets可以。但这也导致gets容易发生缓冲区溢出,因为它不检查输入长度,而scanf可以用%ns来限制读取的字符数。 然后,关于安全性,gets因为不检查输入长度,已经被弃用了,C11标准中甚至移除了它,推荐使用fgets代替。而scanf如果正确使用格式指定符,比如%10s,可以限制输入长度,避免溢出。 另外,返回值方面,scanf返回成功读取的项数,gets在成功时返回指针,失败返回NULL。这可能影响错误处理的方式。 还有,换行符的处理。gets会读取并丢弃换行符,而scanf在读取字符串时会留下换行符在输入缓冲区里,可能会影响后续的输入操作。 可能需要举例说明,比如用scanf("%s", str)输入"hello world",只能读到"hello",而gets会读入整个"hello world"直到换行符。 总结的话,要分点列出区别,并强调安全性的问题,建议使用更安全的函数替代gets,比如fgets。</think>gets()和scanf()在字符串输入上的核心区别体现在以下5个方面,我将通过对比表格+示例说明: $$\begin{array}{|l|l|l|} \hline \textbf{特性} & \textbf{gets()} & \textbf{scanf(\%s)} \\ \hline \text{空格处理} & \text{读取直到换行符(含空格)} & \text{遇到空格/换行立即停止} \\ \hline \text{缓冲区溢出风险} & \text{高危(不检查长度)} & \text{可控(可指定长度如\%10s)} \\ \hline \text{换行符处理} & \text{读取并丢弃} & \text{保留在输入缓冲区} \\ \hline \text{标准兼容性} & \text{C11已废弃} & \text{安全使用需规范} \\ \hline \text{返回值} & \text{成功返回指针,失败NULL} & \text{返回成功读取项数} \\ \hline \end{array}$$ **示例对比:** ```c char str[10]; scanf("%9s", str); // 输入"Hello World" → 存入"Hello" gets(str); // 输入"Hello World" → 完整存入(但会溢出!) ``` **安全建议:** 1. 永远不要使用gets(),改用fgets() ```c fgets(str, 10, stdin); // 安全读取最多9字符 ``` 2. 使用scanf()时必须限制长度 ```c scanf("%9s", str); // 限定不超过数组长度-1 ``` **底层原理:** 当输入超过缓冲区大小时,gets()会直接覆盖相邻内存区域(导致未定义行为),而规范使用的scanf()会截断输入。现代编译器使用栈保护技术(如Canary值)时,gets()触发的溢出会直接导致程序崩溃。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值