推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

输入字符串 进行比较 C语言,C语言字符串输入函数的比较与解析

   2023-08-27 网络整理佚名1510
核心提示:今天把C语言中的三个字符串输入函数(scanf,gets,fgets)深入分析一下,以至于不要让太多ACMer字符串输入的阴沟里翻船。首先讨论一下最常见的scanf输入字符串。如果你的下次输入是输入字符时或者使用gets等函数输入字符串时,你的下次输入就可能会被影响。很明显等待输入的是函数并且字符串str2是一个空串(也就是直接就是字符串结束符'\0'的字符串,长度为0)。

很多在做ACM题的时候经常会被一些字符输入搞糊涂。 如果你认为几个字符串输入函数的功能基本相同,那就大错特错了。 今天就深入分析一下C语言中的三个字符串输入函数(scanf、gets、fgets),免得翻了太多ACMer字符串输入的阴沟。 (仅讨论命令行上的标准输入)

让我们首先讨论最常见的 scanf 输入字符串。 众所周知,使用scanf("%s")输入字符串的一个显着特点就是字符串中不能有空格、回车、制表符等空白字符。 因为scanf遇到空白字符就结束字符串输入。 请看下面这段代码:

### N 20

int main()

字符str[N];

scanf("%s", 字符串);

("%s\n", 字符串);

0;

编译运行后输入“abc def”会发生什么? 程序的结果是什么?下面是我的测试结果

这说明什么? scanf 确实无法读取带有空格字符的字符串。 因此,当需要读取带有空白字符的字符串时,使用scanf是一个不明智的选择。

接下来讲一下scanf函数的一个非常重要的特性:使用scanf函数作为命令行的标准输入,只要以换行符(即回车键)结束输入就可以了使用scanf读取单个字符,那么这个换行符就会被放入输入缓冲区中。 如果您的下一次输入是在输入字符或使用gets等函数输入字符串时,您的下一次输入可能会受到影响。 接下来做一个实验,请看这段代码:

### N 20

int main()

字符str[N];

字符ch;

scanf("%s", 字符串);

("%s\n", 字符串);

ch = ();

("%d\n", ch);

0;

编译运行后,输入“abc”,回车结束输入。 以下是我的测试结果

我使用字符变量ch来接受后续的字符输入,然后打印该字符的ASCII码值。 该字符的ASCII码值为10,正是换行符的ASCII码。 仅仅用scanf输入字符串是不够的,我们应该尝试使用scanf函数输入其他比如整数浮点数来尝试,这里我就不一一写代码进行实验了。 我试了一下,结果还是一样:输出ch的ASCII码值仍然是10。这意味着scanf函数在输入以a结尾时,会将换行符留在输入缓冲区中,而不是清除换行符。换行符。当然我想说的是,这种情况下,scanf后面没有换行符,请看这段代码

### N 20

int main()

字符str[N];

字符ch;

scanf("%s", 字符串);

("%s\n", 字符串);

scanf("%c", &ch);

("%d\n", ch);

ch = (); //读取第二次scanf后剩余的字符,实际上没有

("%d\n", ch);

0;

运行后,使用与上面相同的输入,结果仍然是与上面相同的输出。

但不同的是,程序结束,而是再次等待输入,因为第一次scanf输入后留下的换行符被第二次scanf读取,而换行符之后没有后续输入,所以函数在等待输入。 解释:并不是scanf生成换行符放入输入缓冲区,而是用户输入的换行符没有被scanf吃掉,从而保留在缓冲区中。

接下来是 gets 函数。 当我们需要读取包含空白字符的字符串时,基本上就是 gets 函数。 gets 函数恰好是专门为读取带有空白字符的字符串而设计的。 事实上,gets 函数会一直读取直到换行符停止。 测试代码如下:

### N 20

int main()

字符str[N];

字符ch;

获取(str);

("%s\n", 字符串);

("%c\n", str[(str)-1]); //输出字符串str的最后一个字符,不是'\0'

ch = ();

("%d\n", ch);

0;

当我输入字符串“I am a”并按回车键结束输入时,结果是这样的

ch字符正在等待输入,这意味着gets函数的输入字符串不会像scanf函数那样在输入缓冲区中留下换行符。 那么这个换行符是否被读入字符串中呢? 不! 因为输出字符串的最后一个字符发现这个字符不是换行符而是字母't',而这恰好是我输入字符串的最后一个字符。 可以看出,gets函数会吃掉换行符,但不会将其放入字符串中,这相当于在scanf函数中添加了一个可以读取不是换行符的空白字符的函数。

接下来我们看一下scanf和gets交替使用读取字符串的现象。 测试代码如下:

### N 20

int main()

字符str1[N];

字符 str2[N];

字符ch;

scanf("%s", str1);

获取(str2);

("str1=%s;\n", str1);

("str2=%s;\n", str2);

ch = ();

("ch = %d\n", ch);

0;

我打算先输入“”,然后按回车键输入另一个字符串,但是当我输入完“”并回车时,第二个字符串已经被输入了,现象如下:

显然,等待输入的是一个函数,字符串str2是一个空字符串(即直接是字符串终止符'\0'的字符串,长度为0)。 我们不妨根据之前得到的结论解释一下为什么会这样:scanf函数在输入缓冲区中留下一个换行符,并被gets函数读取,因为gets函数遇到换行符就结束字符串的输入,而换行符之前的字符已经被scanf函数读到了,所以gets函数读到的是一个空字符串,而gets函数会吃掉换行符,不会将其放入字符串中,所以当前函数还在等待用于输入状态。 其实你不妨做一个实验,当你用gets函数输入一个字符串,只按回车键,那么在gets函数中读到的就是一个空字符串。 一个明显的结论是,scanf函数不可能读取空字符串,因为它不会读取空白字符,所以它会一直等待输入,直到出现非空白字符。

接下来我们要讲的是第三个字符串输入函数fgets。 fgets本来是一个文件输入函数,但也可以用于标准输入。 它相对于gets函数的优点是可以限制字符串输入的长度,避免缓冲区溢出。 ,很多网络攻击都是缓冲区溢出攻击。 换句话说,fgets函数比gets函数更安全。 我们仍然使用之前的测试代码,只是将gets替换为fgets,代码如下:

### N 20

int main()

字符str1[N];

字符 str2[N];

字符ch;

scanf("%s", str1);

fgets(str2, (str2), 标准输入);

("str1=%s;\n", str1);

("str2=%s;\n", str2);

ch = ();

("ch = %d\n", ch);

0;

输入仍然完全相同。 输入“”并回车后,fgets就完成了输入。 由此可见,fgets和gets的功能还是很相似的,但是有一处不同。 看看我的结果:

显然,函数仍在等待输入,但字符串str2与之前不同。 应该说fgets函数是在字符串中添加一个换行符。 str2不是一个空字符串,而是一个只有一个换行符的字符串。 字符串,如果输出str2的长度你会发现它的长度为1。fgets和gets在输入字符串中除了限制输入字符串的长度之外的主要区别在于fgets会读取换行符到字符串中像 gets 函数一样破坏换行符。

至此,这三个C语言字符串输入函数的分析比较就结束了。 如果有人发现任何其他谜团,,,别忘了分享,,

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON