文章目录
- 概述
- 转换说明
- int
- float
- double
- 字符串
- 修饰符 modifier
- 格式字符串中的空白
- 格式字符串中的普通字符
- * 修饰符
概述
作用:
Read formatted data from the standard input stream.
函数原型:
int scanf( const char *format [,argument]… );
Parameters:
format: Format control string
argument: Optional arguments
Return Value:
return the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character.
C 语言通过函数原型检查函数调用时的实参个数和类型是否正确。
但是这个机制对于 scanf 和 printf 都不起作用,因为这两个函数的函数原型中参数个数是可变的。
程序员要自己负责转化说明的数量、类型与后面的参数的数量、类型匹配。
从键盘输入的都是文本, 因为键盘只能产生文本字符.
例如, 要输入数字 10, 就要用键盘键入字符 1 和字符 0.
但是计算机中存储的数据都是数值类型, 因此需要将字符转换为数值类型.
scanf 将键入的字符串转换为整数, 浮点数, 字符或字符串等等, 而 printf 要完成的任务则刚好相反, 将整数, 浮点数, 字符和字符串等等转换为显示在屏幕上的文本.
scanf 和 printf 一样也要使用格式字符串和参数列表, scanf 中的格式字符串表明字符输入流的目标数据类型.
scanf 和 printf 的主要区别在于, printf 使用变量, 常量和表达式, 而 scanf 使用指向变量的指针.
转换说明
int
%d
%d 可以识别键入内容中的 +
和 -
和 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
.
float
%f
double
%lf
字符串
%s
只会读取第一个单词, 遇到空白就结束读取, 剩余内容保留在缓存中, 等待下一个读取的命令, 作为下一个读取命令的输入.
代码示例:
#include<stdio.h>
int main(void)
{char str1[10], str2[20];printf("Enter your name: ");scanf("%s", str1);scanf("%s", str2);printf("%s\n", str1);printf("%s\n", str2);return 0;
}
结果:
Enter your name: mike tom
mike
tom
一次性输入两个单词, 用空格分隔, 第一个单词被 scanf("%s", str1);
语句读入, mike
储存在 str1
中, 剩下的空格和 tom
留在缓存中, 遇到 scanf("%s", str2);
语句时被读入, 其中空格被忽略, tom
被储存在 str2
中.
修饰符 modifier
可以在转换说明中 (百分号和转换字符之间) 使用修饰符.
当使用多个修饰符时, 需要按照下表所示顺序书写:
格式字符串中的空白
scanf 使用空白将键入的内容分成多个字段.
在依次将转换说明和字段进行匹配时跳过键入的内容中的这些空白.
唯一例外的是 %c 转换说明, 根据 %c 转换说明, scanf 将会读入键入的每一个字符, 包括空白.
%c 将键入的所有字符都读入, 包括空白.
除了 %c 之外的其他转换说明, 将会跳过键入的内容中的空白, 直到遇到非空白字符, 才开始尝试读取这个非空白字符, 如果符合转换说明要求的格式, 则进行读入, 否则发生错误, 这些键入的内容依然存在于缓存中, 留待下一次读入.
程序在下一次读取时, 首先碰到的是上一次读取时丢弃的内容.
对于带有多个转换说明的 scanf 函数, C 规定, 在第 1 个出错的地方就停止读取输入.
格式字符串中的普通字符
scanf 函数允许把普通字符放在格式字符串中, 除了空格外的普通字符必须与键入的内容严格匹配.
例如下面的这个输入:
scanf("%d,%d",&a,&b);
被解释为: 用户需要键入一个数字, 一个逗号, 一个数字.
由于在这个格式字符串中, 第一个 %d 后面紧跟着一个逗号, 所以在键入的内容中, 第一个数字后面必须紧跟一个逗号.
第二个 %d 在读取键入的内容时, 会跳过第二个数字前面的所有空白.
程序示例:
#include<stdio.h>int main(void)
{int a = 0,b=0;printf("输入两个整数:");scanf("%d,%d", &a, &b);printf("%d %d\n", a, b);return 0;
}
结果1:
输入两个整数:1,2
1 2
可以看出, 两个整数都读取成功.
结果2:
输入两个整数:1 ,2
1 0
a 读取成功, b 读取失败, 还是原来的值, 即 0.
结果3:
输入两个整数:1, 2
1 2
逗号紧跟第一个数, 第二个数和逗号之间可以有空白.
格式字符串中的空白意味着跳过下一个输入项前面的所有空白.
程序示例:
#include<stdio.h>int main(void)
{int a = 0,b=0;printf("输入两个整数:");scanf("%d ,%d", &a, &b);printf("%d %d\n", a, b);return 0;
}
结果1:
输入两个整数:1 ,2
1 2
所有空白也包括没有空白的特殊情况:
结果2:
输入两个整数:1,2
1 2
除了 %c 之外的其他转换说明, 将会跳过键入的内容中的空白, 因此下面这两句话效果相同:
scanf(“%d%d”, &a, &b); // 没有空白
scanf(“%d %d”, &a, &b); // 有空白
根据 %c 转换说明, scanf 将会读入键入的每一个字符, 包括空白. 但是如果 %c 前面有一个空格, 则键入内容中的空白将被忽视, 从第一个非空白字符开始读取.
scanf("%c", &ch);
从键入内容的第一个字符开始读取, 包括空白符.
scanf(" %c", &ch);
从键入内容的第一个非空白字符开始读取.
* 修饰符
把 * 放在 % 和转换字符之间会使得 scanf 跳过相应的输出项.
程序示例:
#include<stdio.h>int main(void)
{printf("Please enter three integers: ");int a = 0, b = 0, c = 0;scanf("%*d %*d %d", &c);printf("The last integer is %d.\n", c);return 0;
}
带了 * 则后面不需要对应的变量去接受键入的内容. 因此这里只需要一个变量 c.
在程序中需要读取文件中特定列的内容时, 这项跳过功能很有用.