《C语言程序设计:问题与求解方法》——2.12节数据输入—格式化输入库函数scanf()的用法

简介:

本节书摘来自华章社区《C语言程序设计:问题与求解方法》一书中的第2章,第2.12节数据输入—格式化输入库函数scanf()的用法,作者:何 勤,更多章节内容可以访问云栖社区“华章社区”公众号查看

2.12 数据输入—格式化输入库函数scanf()的用法
在程序运行过程中,我们想要在某语句处暂时中断程序的运行,通过键盘输入数据到变量所对应的内存单元中,就要在程序中事先写好输入库函数调用语句。scanf()是格式化输入库函数,这是一种经常用到的输入库函数。
格式化输入库函数scanf()的调用,可以使得程序运行暂停下来,等待用户从键盘输入数据。程序用户可以通过键盘输入一个(或多个)数值;输完数据后,还要按下回车键,scanf()函数就会将这个(或多个)输入值(经过转换)存放到变量所对应的内存单元中。从scanf()函数返回后,接着运行程序后面的语句。
不过在调用scanf()函数时,第一个参数是相应的格式符%d、%f或%c,它们与要输入的变量类型的简单对应关系如表2-4所示。


30bb1c8ad0b55eef84dacba88f599c795c829b36

调用库函数scanf(),通过键盘输入一个变量值的最简单形式是:
scanf( "格式符",&变量);
例如:

scanf("%f"  ,  & tenement_area ) ;  // 假设tenement_area是float型变量
scanf("%d"  ,  & age ) ;          // 假设age是int型变量
scanf(" %c"  ,  & ch ) ; //假设ch是char型变量,在 %c 之前,加了一个空格字符
请看以下程序:
#include<stdio.h>
int main(void)
{
    int  num ; 
    float  x ;
    char  ch;
    printf("请输入总人数\n");
    scanf("%d" , & num ) ;
    printf("请输入现在的气温\n");
    scanf ("%f"  ,&x ) ;  
    printf("请输入等级(A、B、C)\n");
    scanf(" %c" ,& ch ) ; //注意:此处在 %c左边加了一个空格,原因请参见书末参考文献

    printf("总人数是:%d\n气温是:%.2f\n 等级是:%c\n" , num, x,ch); //输出变量值
    return  0;
}
程序运行后,人机之间的交互过程如下:
请输入总人数            //计算机显示的输入提示
18                 //程序用户在键盘上输入的数据。“” 表示按下回车键
请输入现在气温          //计算机显示的输入提示
23.6                //用户在键盘上输入的数据
请输入等级(A、B、C)        //计算机显示的输入提示
B                 //用户在键盘上输入的数据
总人数是:18            //计算机显示的输出结果
气温是:23.60            //计算机显示的输出结果
等级是:B                 //计算机显示的输出结果

在本例程序中,交替使用了库函数printf()和scanf(),这使得程序可以在运行时与用户进行实时交互,实现“人机对话”(更准确地说,是计算机用户与运行着程序的计算机对话)。这样编写的程序用户比较喜欢。
常见编程错误:漏写输入项中变量左边的取地址运算符 “&”是调用scanf()函数时最为常见的编程错误。这个错误很可能使得程序在运行时崩溃。例如:
scanf(" %f", tenement_area ) ; //错误!
scanf("%f" , &tenement_area ) ; //正确!
多个变量值的输入
用于多个变量值的输入scanf()函数的调用方式如下:
scanf("格式符1格式符2格式符3",&变量1,&变量2, &变量3) ;
对于scanf()函数调用,格式串中格式符的个数要与输入项一样多,类型也要一一匹配。即格式符1要与变量1的类型匹配,格式符2要与变量2的类型匹配等。
注意:用一次scanf()函数调用,输入多个非字符类型的变量,程序运行时几个输入数据之间要用空格隔开,输完最后一个数据之后,再按下回车键。
但字符变量是例外,几个字符变量的值要连着用键盘输入,输入的字符之间不要用空格隔开,因为空格本身也是一个字符。
字符变量与其他类型数值变量最好不要用同一个scanf()函数调用输入,这样容易在输入时出错。
与printf()类似,在scanf()函数调用时,整型量也不能用格式符%f匹配,实型量也不能用格式符%d匹配。这也是初学者经常犯的严重编程错误。
有了上述这些知识,我们现在可以来完善例题2.5了。请读者先不看答案,自己独立做出来,然后与本书所给的答案比较一下。
经过修改完善的例题2.5如下所示:

1  #include <stdio.h>
2  #define  UNIT_PRICE  1.3   /*单价定义为符号常量*/
3  int  main(void)
4  { 
5    float   tenement_area ;     /*定义变量:住宅面积*/
6    float   management_cost ;   /*定义变量:每月物管费用*/
7    printf("请输入住宅面积,单位是平方米\n");
8    scanf("%f" , & tenement_area );
9    management_cost= UNIT_PRICE * tenement_area ;   /* 求出每月物管费用*/
10   printf("住宅面积% 6.2f平方米 ,物管费% .2f元\n ",tenement_area , management_cost);
11   return  0;
12  }

编译通过后,请重复两次运行此程序,每次输入的面积不同,看看程序是否输出了相应不同的物管费用。
通过在编程时调用输入库函数,才使程序能够及时从输入设备(人操作的键盘)得到变量的当前值。
【问题1】第8行的语句能否写成:

1)  scanf("%f" ,   tenement_area );
2)  scanf("%d" , & tenement_area );
3)  scanf("%f , & tenement_area " );

为什么?
【问题2】如果漏写了上例中第8行的scanf()调用语句,结果将如何?
【问题3】能否将变量 tenement_area 定义为int型? 为什么?
延伸与拓展:printf()函数与scanf()函数调用时的一些重要区别
虽然格式化输入库函数scanf()在用法上与printf()有不少类似之处,但是,两者之间在使用上,也有以下所列的重要不同之处:
1)在printf()的格式串中可以使用转义字符 n来换行,但在scanf()的格式串中却不能使用转义字符 n(也不能使用其他一些转义字符)。
2)scanf()的格式串后面的参数是输入数据的存放地址,所以在通常情况下,变量名左边的取地址符号“&”是绝不能漏写的。例如,如果age是int型变量,那么

scanf("%d" , &age); 
不能写成
scanf("%d" , age);
然而,对于printf()函数来说,以下语句却常常是一种误写:
printf("%d" , &age);   
在VC++ 6.0编译环境下,这只是输出了变量age的内存地址。正确形式是:
printf("%d" , age);
这样才是输出变量age的值。
3)对于printf()函数来说,
printf("%d%d%d", n1,n2,n3) ;
不是好的形式,三个变量的值在输出时根本区分不开;而
printf("n1=%d,n2=%d,n3=%d", n1 , n2 , n3 ) ;
却是比较好的形式。
但是对于scanf()来说:
scanf("%d%d%d", &n1 , &n2 , &n3 ) ; 
通常比较好,在输入三个数据之间只需输入一个空格将其分开;而
scanf("n1=%d,n2=%d,n3=%d",& n1 , &n2 , &n3 ) ;

却非常不好。你必须先从键盘键入“n1=”这些字符之后,才能输入变量n1的值,整个输入过程非常麻烦,完全是自讨苦吃。不信你可以亲自试一试。
4)printf()的输出项既可以是表达式和变量,也可以是常量和函数调用(注意:其实它们本质上都是表达式);而scanf ()的输入项通常只能是变量的地址,不能是通常的表达式。

相关文章
|
11天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
2天前
|
传感器 人工智能 物联网
【C 言专栏】C 语言与硬件交互的方法
【5月更文挑战第4天】C 语言在硬件交互中扮演关键角色,主要通过直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射I/O和设备驱动程序开发。挑战包括硬件多样性、实时性要求和错误处理。随着物联网和人工智能发展,C语言与硬件交互的需求增加,未来将面临更多新硬件和技术的挑战。本文旨在帮助读者理解和掌握这一领域的知识,以实现更高效的硬件互动。
【C 言专栏】C 语言与硬件交互的方法
|
5天前
|
缓存 安全 编译器
【C 言专栏】C 语言函数的高效编程技巧
【5月更文挑战第1天】本文探讨了C语言中函数的高效编程技巧,包括函数的定义与作用(如代码复用和提高可读性)、设计原则(单一职责和接口简洁)、参数传递方式(值传递、指针传递和引用传递)、返回值管理、调用约定、嵌套与递归调用,以及函数优化技巧和常见错误避免。掌握这些技巧能提升C语言代码的质量和效率。
【C 言专栏】C 语言函数的高效编程技巧
|
5天前
|
算法 C语言
【C 言专栏】C 语言文件操作的技巧与方法
【4月更文挑战第30天】本文介绍了C语言文件操作的关键技巧,包括文件的打开与关闭(使用`fopen`和`fclose`函数),读取(`fgetc`、`fgets`和`fread`)和写入(`fputc`、`fputs`和`fwrite`)操作。此外,还讨论了文件指针移动(`fseek`)、错误处理、文件权限和格式等问题。文中提供了一个简单的读写文件的示例,并提到了高级技巧如随机访问、文件缓冲和截断。掌握这些技能将有助于提升C语言编程中的文件处理能力。
|
8天前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
|
8天前
|
C语言
C语言 浙大版《C语言程序设计(第3版)》题目集 练习8-8 移动字母 (10分)
C语言 浙大版《C语言程序设计(第3版)》题目集 练习8-8 移动字母 (10分)
|
8天前
|
C语言
浙大版《C语言程序设计(第3版)》题目集 练习8-2 计算两数的和与差 (10分)
浙大版《C语言程序设计(第3版)》题目集 练习8-2 计算两数的和与差 (10分)
|
8天前
|
C语言
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
|
8天前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-6 删除字符 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-6 删除字符 (20分)
|
8天前
|
C语言
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)