scanf()作为 C 语言中的基本输入,曾经带给我们初次编写 C 程序的快乐。但是随着
C 的不断深入,我们却发现:原来最难理解的东西居然是我们自以为很熟悉的东西。
我们真正了解 scanf()吗?那么看看下面的几个例子吧。
一、关于 scanf()中的格式控制符
scanf()的格式控制符有多个,但我只想讨论一下%[]这个格式控制符。%[]可以用来进
行多个字符的输入,并对结束符进行自定义。
ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一
个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对
方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf()
读入字符 A、B 和 C:
%[ABC]
使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集
合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入
字符组成的字符串。
对于许多实现来说,用连字符可以说明一个范围。 例如,以下扫描集使 scanf() 接受字
母 A 到 Z:%[A-Z] 重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写
字符时,应该分别说明大、小写字母。
对于%[]还可以用^+任意字符(包括 eof)来结束字符串的输入。比如%[^EOF]就是直到有
EOF 输入,字符串才中止。
但一定要记住就是 c 语言是缓冲输入,即使你%[^a],再你输入回车之前输入多少的 a 都是
不可能结束的。
如下面的一段程序:
#include<stdio.h>
int main()
{
char string[50];
/*scanf("%s",string);不能接收空格符*/
printf("Input [^\\n] string \n");
scanf(" %[^'\n']",string);
printf("The s[^\\n] string :%s\n",string);
fflush(stdin);
printf("Input [^a] string \n");
scanf(" %[^a]",string);
printf("'a' ends input :%s\n",string);
printf("Input [A-F] string\n");
scanf(" %[A-F]",string);
printf("String is: %s\n",string);
return 0;
}
运行结果:
ghost@ghost-desktop:~/Desktop/testzone/first$ ./t
Input [^\n] string
I love China!
The s[^\n] string :I love China!
Input [^a] string
I love youa
'a' ends input :I love you
Input [A-F] string
String is: I love you
ghost@ghost-desktop:~/Desktop/testzone/first$
通过上述运行结果,可能会感到疑惑,为什么 Input [A-F] string 根本就没有输入,哪来
的输出呀?这个问题就是我们将要讨论的话题。
二、关于 scanf()的异常情况
scanf()会产生什么异常呢?
先来看一段程序:
#include<stdio.h>
int main()
{
int i;
char ch;
for(i=0;i<=3;i++)
{
printf("%d ---- ",i);
scanf("%c", &ch);
printf("\n");
//scanf("%*c");
//printf("\n%c\n",ch);
//getchar();
}
return 0;
}
运行结果:
ghost@ghost-desktop:~/Desktop/testzone/first$ ./t
0 ---- a
1 ----
2 ---- b
3 ----
ghost@ghost-desktop:~/Desktop/testzone/first$
产生其原因在于:
因为 scanf %c 只是读入一个字符,而你在输入时实际上输入的是:某个字符
+Enter,Enter 产生的\n 也会停留在输入缓冲区中,下次调用 scanf %c 时就会直接读到
它而不是等待你再次输入!同理,getchar()也有类似的行为。所以我们才不提倡使用
scanf("%c", ...),尤其是把它在循环中。
解决的方法:
(1)、将 scanf("%c", &ch); 修改为:
scanf(" %c", &ch); /*在%前加上一个空格*/
(2)、将 scanf("%c", &ch); 修改为:
scanf("%c%*c", &ch);
(3)、函数名: fflush
功 能: 清除一个流
用 法: int fflush(FILE *stream);
#include <stdio.h>
int main()
{
int a;
char c;
do{
scanf("%d",&a);
fflush(stdin);
scanf("%c",&c);
fflush(stdin);
printf("a=%d c=%c\n",a,c);
}while(c!='N');
return 0;
}
(4)、如何处理 scanf()函数误输入造成程序死锁或出错?
#include <stdio.h>
int main()
{
int a,b,c; /*计算 a+b*/scanf("%d,%d",&a,&b);
c=a+b;
printf("%d+%d=%d",a,b,c);
return 0;
}
如上程序,如果正确输入 a,b 的值,那么没什么问题。但是,不能保证使用者每一
次都能正确输入,一旦输入了错误的类型,你的程序不是死锁,就是得到一个错误的结果,
这可能所有人都遇到过的问题吧?
解决方法:scanf()函数执行成功时的返回值是成功读取的变量数,即:这个 scanf ()
函数有几个变量,如果 scanf()函数全部正常读取,它就返回几。但这里还要注意另一个
问题,如果输入了非法数据,键盘缓冲区就可能还个有残余信息问题。
正确的例程:
#include <stdio.h>
int main()
{
int a,b,c; /*计算 a+b*/
while(scanf("%d,%d",&a,&b)!=2)
fflush(stdin);
c=a+b;
printf("%d+%d=%d",a,b,c);
return 0;
}
原地址:http://blog.chinaunix.net/u1/54577/showart_1086492.html
分享到:
相关推荐
在C语言中,我们可以使用内置的函数如`printf`和`scanf`,以及一些基本的数学运算来实现这个功能。 首先,我们要理解整数部分的转换。例如,将十进制整数转换为二进制,可以采用除二取余的方法,每次将整数除以2...
标题:初学者学习C语言中常见问题的探讨 描述:本文旨在探讨初学者在学习C语言过程中经常遇到的问题,通过分类列举常见错误,并进行分析与探讨,从而帮助初学者借鉴和避免这些问题,提高学习效率。文章结合了作者...
本教程“C_function_example.rar”旨在深入探讨C语言中的库函数及其使用方法,帮助学习者更好地理解和应用C语言。 首先,我们要理解C语言的库函数分为标准库函数和非标准库函数。标准库函数是C语言规定的一部分,如...
本文将深入探讨C语言中的自增、自减运算符优先级差异、二维数组的使用以及程序设计和调试的技巧,帮助学生和开发者更好地掌握C语言编程。 首先,C语言的运算符优先级对于程序的正确执行至关重要。自增和自减运算符...
因此,在实际开发中,通常会采取混合编程的方式,即大部分逻辑使用C语言实现,而关键性能部分使用汇编语言编写,从而达到既高效又易于管理的目的。 #### 混合编程的方法 ##### C程序中内嵌汇编指令 C语言提供了一...
在编程世界中,C语言是一种基础且强大的编程语言,它被广泛用于系统开发、软件构建以及各种嵌入式系统。进制转换是编程中的基础知识,尤其是在处理二进制、八进制、十进制和十六进制数据时。C语言提供了多种方法来...
在这个“scanf 键盘输入”的主题中,我们将深入探讨 `scanf` 的用法、优点、缺点以及如何在实际编程中有效地使用它。 首先,`scanf` 函数的基本语法如下: ```c int scanf(const char *format, ...); ``` 这里的 ...
- 格式输入与输出部分,讲解了printf、scanf等标准输入输出函数的使用方法和技巧,并涉及到了类型转换、输入输出缓冲等高级话题。 - 运算符与表达式部分,对C语言中的各种运算符进行了分类,并详细讨论了运算符的...
本文将从C语言的技术特性、指针应用、算法技巧、语句利用和恢复现场等方面,探讨C语言在计算机软件编程中的应用,并提出未来应用的建议。 首先,C语言的技术特性主要体现在对程序模板的细化处理,即将大模板划分为...
4. 结构体和联合体:C语言允许程序员通过结构体和联合体来构造复杂的数据类型,书中对这些高级数据结构及其使用方法进行了阐释。 5. 预处理器:预处理器在C程序编译之前运行,用于处理宏定义和文件包含等任务,书中...
书中涵盖了C语言的基础语法、标准库的使用方法以及编程实践等内容,并且通过大量的示例代码帮助读者理解和掌握C语言的核心概念。 ### C语言基础知识 1. **数据类型**:C语言支持多种基本数据类型,包括整型(int)、...
在本篇文章中,我们将深入探讨C语言标准库函数,理解它们的功能、用法以及在实际编程中的应用。 1. **输入/输出函数**: - `printf()` 和 `scanf()`:这两个函数是最基本的输入输出函数,分别用于格式化输出和输入...
下面我们将深入探讨C语言和C++中的库函数,了解它们的使用方法和重要性。 1. **C语言库函数** C语言的库函数主要包含在标准库`<stdio.h>`、`<stdlib.h>`、`<string.h>`、`<math.h>`等中。例如: - `stdio.h`:...
本文将深入探讨C语言的核心概念、基本语法、常用数据类型、控制结构、函数应用以及一些典型的实践用法。 1. **基本语法**:C语言的语法简洁而严谨,它以分号作为语句的结束符,使用大括号{}来组织代码块。程序由...
在C语言中,我们可以使用以下方法进行进制转换: 1. **手动转换**: - 从十进制到其他进制:可以使用除法和模运算(%)来逐步获取每一位数字。 - 从其他进制到十进制:可以使用乘法和累加,结合字符串处理将数字...
- **数组**:讨论固定长度和变长数组的概念及使用方法。 - **指针**:详细解释指针的基本概念,如声明、初始化、解引用等,以及它们在C编程中的重要作用。 - **动态内存管理**:介绍如何使用malloc、free等函数进行...
书中详细讲解了这些函数的使用方法,以及如何进行格式化输出和错误处理。 6. **文件操作**:C语言提供了打开、关闭、读取和写入文件的接口。学习这部分内容有助于理解如何在程序中处理文件数据,例如保存和加载用户...
这些结构是编写复杂逻辑的基石,书中通过实例向读者展示了它们的使用方法。 此外,书中也介绍了C语言中的数据类型,包括基本数据类型(如`int`、`char`、`float`和`double`)以及它们的变体(如`short`和`long`)。...
- **结构体指针** —— 探讨了指向结构体的指针的使用方法。 ##### 第7章:输入与输出 - **标准输入输出** —— 介绍了如何使用标准输入输出流(`stdin`和`stdout`)。 - **文件输入输出** —— 讲解了文件操作的基础,...