关于【C语言】中scanf与getchar的用法和常见错误详解

您所在的位置:网站首页 scanf函数输入字符要取地址吗 关于【C语言】中scanf与getchar的用法和常见错误详解

关于【C语言】中scanf与getchar的用法和常见错误详解

2024-07-10 15:56| 来源: 网络整理| 查看: 265

写这篇博客的起因是最近博主自己学习中总是遇到类似的错误,并曾百思不得其解。 今天分享出来是希望帮助大家在写代码时避免这些错误。话不多说,我们直接开始吧!

在这里插入图片描述

君兮_的个人主页

勤时当勉励 岁月不待人

C/C++ 游戏开发

输入函数scanf与getchar 一.scanf的用法1. scanf(“输入控制符”, 输入参数);2.scanf(“输入控制符非输入控制符”, 输入参数)输入多个参数 3.scanf的返回值 二.getchar的用法1.getchar的返回类型及使用效果 三.几种常见错误详解1.不理解原理导致的错误2.输入参数不符合输入控制符要求 总结参考博客

一.scanf的用法 我们先来看看再MSDN里对scanf的解释 在这里插入图片描述 - scanf 的功能用一句话来概括就是“通过键盘给程序中的变量赋值”。下面来讲讲它的两种基本用法: 1. scanf(“输入控制符”, 输入参数);

功能:将从键盘输入的字符转化为“输入控制符”所规定格式的数据,然后存入以输入参数的值为地址的变量中。

在通常情况下,我们不希望某个值是由我们程序员指定的,而是在程序运行中由用户从键盘输入的,这更能满足在日常使用时用户的需要,提高我们程序的灵活性用 scanf 即可实现即可很好的满足我们的要求: # include int main() { int n=0; scanf("%d", &n); //&n 表示取变量 n 的地址,&是取地址符 printf("n = %d\n", i); return 0; }

上面这个基本的程序中,有以下两点需要注意:

(1)我们从键盘输入的全部都是字符。比如从键盘输入 125,它表示的并不是数字 125,而是字符 ‘1’、字符 ‘2’ 和字符 ‘5’。 操作系统在接收键盘数据时会将它当成字符来接收。这时就需要用“输入控制符”把它转化成相应的内容(如%d 是有符号十进制数 %f 是浮点数)。

上面代码中的%d就是要将从键盘输入的这些合法的字符转化成对应的十进制数字。比如经过 %d 转化之后,字符 125 就是数字 125 了。

(2)&是一个取地址运算符,&加变量名表示“该变量的地址”,所以&n就表示变量 n 的地址。又称为“取地址n”,相当于将数据存入以变量 n 的地址为地址的变量中(即存入变量n的地址中)。也就是把转化后的数字125放到变量 n 中

总的来说 scanf 语句的意思就是:从键盘上输入字符 125,然后%d将这三个字符转化成十进制数 125,“&n” 找到变量 n 的地址,把数字 125 放到以变量 n 的地址为地址的变量中,即变量 i 中,所以最终的输出结果就是n=125。

注意:

int main() { char n[20] = {0}; printf("请输入:>"); scanf("%s", n); } 很多初学者看到这段代码可能会想:这个scanf中没有加&n,会不会是错的?恭喜你!!!---------------------------------------------------回答错误我们要透过代码看到其本质,这段代码在使用时,是把输入的字符串放到一个名字为n的char类型的数组的首地址中,而不是变量n中,把输入值放在地址里,当然是对的。 2.scanf(“输入控制符非输入控制符”, 输入参数)

这种用法我是墙裂建议大家在平时敲代码时不要去使用的,因为在使用过程中对用户非常不友好。但咱们这里是介绍用法,还是简单介绍一下,顺便讲讲改进的方法。

# include int main(void) { int n; scanf("n = %d", &i); printf("n = %d\n", i); return 0; } 在 scanf 中,所有的“非输入控制符”都要原样输入。接下来我来讲讲为什么不推荐使用这种用法这种输入方法必须满足原样输入,当用户使用时,但凡输入的和你设置的格式有一点不同都不行,哪怕只是多或者少了一个空格。比如要从键盘给变量 n 赋值 123,那么必须要输入n=123才正确,少一个或者多一个都是错误的。

改进方法:

int main() { int n; printf("请输入 n = "); scanf("%d", &n); printf("n = %d\n", n); return 0; }

通常在输入前我们加上类似“请输入 n = ”这种代码的目的是提示用户应该输入什么内容,改善用户的使用体验。

具体效果 在这里插入图片描述

这样改进既改进了我们的输入格式,又不至于在使用scanf时出错。

输入多个参数 # include int main(void) { int m, n; scanf("%d%d", &m, &n); printf("m = %d, n = %d\n", m, n); return 0; }

通过键盘给多个变量赋值与给一个变量赋值其实是一样的。比如给两个变量赋值就写两个 %d,然后“输入参数”中对应写上两个 “取地址变量” ;给三个变量赋值就写三个 %d,然后“输入参数”中对应写上三个 “取地址变量” ……

从键盘输入数据时,给多个变量赋的值之间一定要用空格、回车或者 Tab 键隔开,用以区分给不同变量赋的值。而且空格、回车或 Tab 键的数量不限。一般使用一个空格即可。

3.scanf的返回值 scanf的返回值我有一篇博客有具体介绍,这里不过多缀叙,博客链接如下:关于C语言中scanf多组输入的实现 二.getchar的用法 1.getchar的返回类型及使用效果 getchar常用来读取字符以下为msdn中的解释 在这里插入图片描述 int getchar(void)

返回类型为int,参数为void.

getchar返回的其实是字符的ASCII码值(整数)。getchar在读取结束或者失败的时候,会返回EOF(end of file,本质上是-1.)。接下来通过代码简单解释一下 #include int main() { int n = 0; while ((n = getchar()) != EOF)//判断返回值是否是EOF { putchar(n);//打印输入的n } return 0; }

注意:

使用getchar时,每次getchar只会读取一个字符如果上面的代码不用while循环的话,输入123,putchar就只会输出1。 三.几种常见错误详解 1.不理解原理导致的错误 下面以getchar为例具体讲解一下这种错误的产生及解决方法代码如下: #include int main() { char password[20] = {0}; printf("请输入密码:"); scanf("%s", password);//以字符串的形式输入 printf("请确认密码(Y/N):>");//用户输入Y/N确认 int ch = getchar(); if (ch == 'Y') { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; } 来看看这段代码运行的结果 在这里插入图片描述嗯?什么情况,我还没输入Y或N怎么就确认失败了??

在这里插入图片描述

好了,这里我就不卖关子了。 在这里插入图片描述scanf和getchar这两个输入函数,它们都是从键盘上得到我们的数据,而不是直接从键盘上来读取我们的数据。它们和键盘之间有一个区域叫输入缓冲区。所有输入的数据都会先放在输入缓冲区中。在存放输入的数据时,输入函数先来看看输入缓冲区中是否有数据,如果有,它就直接拿走并储存,而不需要从键盘再输入数据,如果输入缓冲区中什么都没有,则需要从键盘输入,再拿走。带入上面的代码试试 在这里插入图片描述当我们输入123456时,为了把“123456”放进去,其实还敲了一个回车,因此实际上输入缓冲区中存放的是“123456\n”。

在这里插入图片描述

程序继续运行,此时它把“123456”提取出来,输入缓冲区中还留有一个“\n”. 在这里插入图片描述

注意: 程序走到这一步后,进行第二次从键盘中读取( int ch = getchar() ),此时输入缓冲区中还滞留有上次未提前出来的“\n”,因此不再从键盘上读取数据,直接把“\n”从输入缓冲区提取出来。此时ch的地址中存放的就是“\n”,显然不等于’Y’,所以输出为“确认失败”

看了上面的讲解,你弄懂了吗?接下来我们来讲讲改进方法

其实改进很简单,它不是在输入缓冲区中还滞留有“\n”吗?我再使用一个输入函数把它给读走不就行啦? int main() { char password[20] = { 0 }; printf("请输入密码:"); scanf("%s", password); printf("请确认密码(Y/N):>"); getchar();//把多余的\n取走 int ch = getchar(); if (ch == 'Y') { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; }

在这里插入图片描述

这种方法雀氏可行,但是如果这样呢?

请输入密码:12345 6(中间加空格)

在这里插入图片描述

?怎么又这样了??我不是把“\n”读走了吗?解释亿下: 在这里插入图片描述此时输入缓冲区中是这样的。

在这里插入图片描述

轮到scanf来取缓冲区中的数据,当它读到空格的时候,它就不再继续往下读了(这是scanf的一个作用性质)。所以scanf就只取走了12345,而缓冲区中还剩下(空格)6\n。 在这里插入图片描述此时,getchar()读取一个字符,它把空格给读走了,输入缓冲区中剩下6\n. 在这里插入图片描述最后,int ch = getchar()把6给读走,不等于’Y’,于是打印“确认失败” 在这里插入图片描述 难道没有什么办法避免这种错误吗?什么话,没有办法我会把这种错误写出来吗??这不是自己打自己脸吗?解决方案 介于输入缓冲区中一直存放有数据未被清理,我们需要把缓冲区中多余的数据先全部清走。方式: 采用一个循环,只要没读到\n,我们就一直用getchar读。代码实现如下: #include int main() { char password[20] = {0}; printf("请输入密码:"); scanf("%s", password); while ( getchar() != '\n');//把缓冲区中多余的内容全读走,直到\n停止 printf("请确认密码(Y/N):>"); int ch = getchar(); if (ch == 'Y') { printf("确认成功\n"); } else { printf("确认失败\n"); } return 0; } 结果: 在这里插入图片描述完美解决

在这里插入图片描述

2.输入参数不符合输入控制符要求 比如以下代码: # include int main(void) { char m; int n; scanf("%c%d", &m); printf("m = %c, n = %d\n", m, n); return 0; } 不做过多解释,scanf中输入控制符要求你输入两个数据,结果你的输入参数只输入了一个,你觉得这可能正确吗?但其实对于多组输入来说,不输入正确个数的数据也有一定意义,详情可以看看我的这篇博客:关于C语言中scanf多组输入的实现需要注意的是:一但发生这种错误时,编译器可能并不会报错,但是从程序上来说它是绝对错误的,当发现异常时,一定要多多注意认真检查一下输入函数。 总结

以上就是今天要讲的所有内容啦 有任何疑问欢迎在评论区或者私信博主指出哦。

大噶(家)下次见啦!

如果感觉有帮助的话不妨三连一下这个新人博主。你们的支持就是我更新的动力。

(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧) 在这里插入图片描述

参考博客 C语言中scanf函数用法详解关于getchar的用法及实例解析


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3