调用scanf函数的一个陷阱
我们在写C程序时,经常使用scanf函数,让用户输入数据,可是有时候会出现一些很奇怪的问题。例如,下面的程序是一个简单的四则运算:
#include <stdio.h> int main()
{
char ope = '\0';//操作符+ - * /
int para1 = 0, para2 = 0, result = 0;//para1是运算参数1,para2是运算参数2,result是运算结果 printf("请输入第一个运算参数\n");
scanf("%d",¶1);
printf("请输入运算符 '+ - * /'\n");
scanf("%c",&ope);
printf("请输入第二个运算参数\n");
scanf("%d",¶2);
switch(ope)
{
case '+': result = para1 + para2;//如果运算符是+,就执行加法运算
break;
case '-': result = para1 - para2;//如果运算符是-,就执行减法运算
break;
case '*': result = para1 * para2;//如果运算符是*,就执行乘法运算
break;
case '/': result = para1 / para2;//如果运算符是/,就执行除法运算
break;
default: printf("运算符输入错误\n");//
break;
}
printf("运算结果是: %d\n", result);
return 0;
}
此程序不管从语法,还是逻辑上,都没有问题,且编译也能通过。实际运行时,却是如下结果:
在用户输入第一个运算参数后,按照程序的设定,应该让用户输入运算符,可是直接让用户输入第二个运算参数了。你能看出这是为什么吗?
我们修改下程序,如下:
#include <stdio.h> int main()
{
char ope = '\0';//操作符+ - * /
int para1 = 0, para2 = 0, result = 0;//para1是运算参数1,para2是运算参数2,result是运算结果 printf("请输入第一个运算参数\n");
scanf("%d",¶1);
printf("请输入运算符 '+ - * /'\n");
scanf("%c",&ope); printf("运算符是: %d\n", ope);
printf("请输入第二个运算参数\n");
scanf("%d",¶2);//加入这两行代码
switch(ope)
{
case '+': result = para1 + para2;//如果运算符是+,就执行加法运算
break;
case '-': result = para1 - para2;//如果运算符是-,就执行减法运算
break;
case '*': result = para1 * para2;//如果运算符是*,就执行乘法运算
break;
case '/': result = para1 / para2;//如果运算符是/,就执行除法运算
break;
default: printf("运算符输入错误\n");//
break;
}
printf("运算结果是: %d\n", result);
return 0;
}
我们加入两行代码,输出字符参数ope的ASCII码值,结果如下:
可以看到,ope的ASCII码值是10,正是换行符的ASCII码值。我们什么时候把换行符给了ope?
其实,在我们给运算参数para1赋值1的时候,我们按下了回车键,准备输入运算符,可是系统不懂啊,系统把回车键理解为换行符赋值给了ope,所以接下来会跳过让用户输入运算符而直接让用户输入运算参数2了,问题就在这里。
知道了问题所在,那么就好解决了。
请看:
#include <stdio.h>
#include <conio.h> int main()
{
char ope = '\0';//操作符+ - * /
int para1 = 0, para2 = 0, result = 0;//para1是运算参数1,para2是运算参数2,result是运算结果 printf("请输入第一个运算参数\n");
scanf("%d",¶1);
getchar(); printf("请输入运算符 '+ - * /'\n");
scanf("%c",&ope);
getchar();
printf("运算符是: %d\n", ope);
printf("请输入第二个运算参数\n");
scanf("%d",¶2);
switch(ope)
{
case '+': result = para1 + para2;//如果运算符是+,就执行加法运算
break;
case '-': result = para1 - para2;//如果运算符是-,就执行减法运算
break;
case '*': result = para1 * para2;//如果运算符是*,就执行乘法运算
break;
case '/': result = para1 / para2;//如果运算符是/,就执行除法运算
break;
default: printf("运算符输入错误\n");//
break;
}
printf("运算结果是: %d\n", result);
return 0;
}
在每次scanf结束后,加入getchar函数,即可。getchar函数从输入流中读取一个字符,因此可以接收我们每次按下的回车键,也就是换行符。运行结果如下:
调用scanf函数的一个陷阱的更多相关文章
- Android中调用C++函数的一个简单Demo
这里我不想多解释什么,对于什么JNI和NDK的相关内容大家自己去百度或谷歌.我对Android的学习也只是个新手.废话少说直接进入正题. 一.在Eclipse中创建一个Android Applicat ...
- Delphi中返回类型为string的函数的一个陷阱(不是很懂)
如果类的一个成员函数的返回值是string类型,需要注意一个问题 其返回值可能是错误的 例如函数的实现如下 function GetString( s: string ): string;begin ...
- C语言scanf函数详细解释
原文链接 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准 ...
- scanf函数
一. 变量的内存分析 1. 字节和地址 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”. 1> 内存以“字节为单位” 0x表示的是十六进制,不用过于纠结,能看懂这些 ...
- 【C语言】05-printf和scanf函数
一.printf函数 这是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据 1.用法 1> pr ...
- 黑马程序员——C语言基础 scanf函数 基本运算 三目运算符
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (一下内容是对黑马苹果入学视频的个人知识点总结) (一)scanf函数 1> 简单介绍一下scanf函数 这是在 ...
- 【学习笔记】【C语言】scanf函数
1. 简介 这也是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>.调用scanf函数时,需要传入变量的地址作为参数,scanf函数会等待标准输入设 ...
- C语言第五节scanf函数
变量的内存分析 字节和地址 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的"字节"和"地址". 内存以"字节为单位" 0x表示的 ...
- 【C语言】03-printf和scanf函数
一.printf函数 这是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据 1.用法 1> pr ...
随机推荐
- 【Repo】推送一个已有的代码到新的 gerrit 服务器
1.指定项目代码库中迭代列出全部ProductList(.git)到pro.log文件中 repo forall -c 'echo $REPO_PROJECT' | tee pro.log 命令解读: ...
- Android零基础入门第25节:最简单最常用的LinearLayout线性布局
原文:Android零基础入门第25节:最简单最常用的LinearLayout线性布局 良好的布局设计对于UI界面至关重要,在前面也简单介绍过,目前Android中的布局主要有6种,创建的布局文件默认 ...
- JAVA 与 PHP 的不同和相同
Java语言与PHP语言因为都可以做web应用开发,所以总有入门学习这2种语言的入门者会问Java和PHP哪一个好.讨论语言的好坏是一件不太明智的事情,我认为只能去说那一种编程语言更加适合干什么,人与 ...
- FMX 动态创建 和 销毁(释放free) 对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- 小试X64 inline HOOK,hook explorer.exe--->CreateProcessInternalW监视进程创建
原始函数是这样的 kernel32!CreateProcessInternalW: 00000000`7738e750 4c8bdc mov r11,rsp 00000000 ...
- 地球坐标-火星坐标-百度坐标及之间的转换算法 C#
美国GPS使用的是WGS84的坐标系统,以经纬度的形式来表示地球平面上的某一个位置.但在我国,出于国家安全考虑,国内所有导航电子地图必须使 用国家测绘局制定的加密坐标系统,即将一个真实的经纬度坐标加密 ...
- Oracle数据库备份和恢复的基本命令
Oracle数据库备份与恢复基本命令 1. 获取帮助 $ exp help=y $ imp help=y 2.三种工作方式 (1)交互式方式 $ exp 然后按提示输入所需要的参数 (2)命令行方式 ...
- django自带的cache
cache语法 from django.core.cache import cache #存入内存 cache.set("aaa",123) #从内存中获取 cache.get(& ...
- 解决Linux和Windos不同步的问题
两种方式: 一:在windos上进行操作 (1).cmd中输入如下命令 Reg add HKLM\SYSTEM\CurrentControlSet\Control\TimeZone ...
- netcore mvc快速开发系统(菜单,角色,权限[精确到按钮])开源
AntMgr https://github.com/yuzd/AntMgr 基于netcore2.0 mvc 开发的 快速搭建具有如下特色的后台管理系统 特色: 用户管理 菜单管理 角色管理 权限管理 ...