要点3:输入函数对比与自定义输入方式
2020-08-18 00:16
483 查看
读取输入的方式
相关函数原型(从控制台获取输入,不考虑宽字符):
int scanf( const char *format, ... ); int getchar(void); char *gets( char *str ); char *gets_s( char *str, rsize_t n ); char *fgets( char *str, int count, FILE *stream );
- scanf 如果解析错误,内容继续留在缓冲区供下次使用;
- 解析失败返回0,成功返回解析的参数个数,不会超过占位符个数,读到文件尾返回EOF(-1);
- 读取字符串,一次只能读取一个词,不能用scanf读取一行;
-
可以读取到换行符;
-
读取一行,遇到换行符,直接丢弃换行符;
\0;
-
可以设置读取的字符串长度;
-
可以设置读取的字符串长度;
scanf
该函数可以从标准输入读取内容,返回值为读取的参数个数,例如:
#include <stdio.h> int main() { int seed; printf("%d\n", scanf("%d %d", &seed, &seed)); }
运行程序,输入 两个整数,打印为 2,测试输入3个值仍然打印2,是因为这个"%d %d"指定了只解析两个int,多余的将留在缓冲区中,如果后面再写一个scanf,将从缓冲区中继续解析。
现在多加一个
scanf:
#include <stdio.h> int main() { int seed; printf("%d\n", scanf("%d %d", &seed, &seed)); printf("%d\n", scanf("%d %d", &seed, &seed)); }
case1:读取到文件尾部返回EOF
1
输出:
1-1
scanf从缓冲区中解析,返回解析成功的参数个数,因为只有一个1,所以第一个给scanf解析,第一行打印1,第二行解析的时候因读取到了文件结束表示
EOF返回-1。
case2:解析失败返回0
f
输出:
0 0
这说明,解析失败的内容还留在缓冲区给下次scanf用,所以两个scanf都返回的0。
因为无法解析的值会继续留在缓冲区供下次使用,所以如果是循环
scanf,程序就会跑飞,让你没有输入的机会,可以使用综上一节提供的示例测试一下,运行后直接输入
f。
case3:返回值最大为占位符个数
1 2 3 4 5 6 7
输出:
2 2
这表明,返回值最大是占位符的个数,剩下的内容还留在缓冲区。
综上
scanf判断输入结束,只能在文件输入模式下利用
EOF判断,例如:
// qwer.c #include <stdio.h> int main() { int a; while(scanf("%d", &a) != EOF) { printf("%d\n", a); } return 0; }
输入文件
test.txt内容:
12 3 4
编译:
gcc qwer.c -o main -std=c11。
运行:
./main < test.txt。
getchar
这个函数可以从输入缓冲区仅读取一个字符,返回int,后面结合
fgets使用。
gets
在读取字符串时,
scanf()和转换说明
%s只能读取一个单词,可是程序中经常要读取一整行输入。
gets函数简单易用,它读取整行输入,直到遇到换行符,然后丢弃换行符,存储其余字符,并在这些字符的末尾添加一个空字符使其成为一个c字符串。它经常和
puts函数配对使用,该函数用于显示字符串,并在末尾添加换行符。
#include <stdio.h> #define STLEN 81int main() { char words[STLEN]; puts("Enter a string, please."); gets(words); // 典型用法 printf("Your string twice:\n"); printf("%s\n", words); puts(words); puts("Done."); return 0; }
printf("%s\n", words);和
puts(words);效果相同,但是编译的时候会产生警告,因为
gets读取整行输入,并不知道
words能存多少,如果输入字符串过长,会导致缓冲区溢出。
例如将
STLEN设置成
5,程序依然可以运行,尝试输入过长的数据就可能会发成溢出,最直观的就是可以看到发生段溢出后程序异常退出。
gets_s
该函数是c11才有的,且为拓展函数,使用方式除了可以设置读取的字符数之外和
gets函数用法一样。
fgets
这个函数除了可以从标准输入读取字符串之外,还可以从文件中读取,而且可以指定读取字符个数,比
gets_s更加灵活易用,利用
fgets,但是
fgets不会自动丢弃超过字符个数之外的行缓冲区数据,所以要配合
getchar将剩余的缓冲数据丢弃,否则可能造成程序运行以异常。
s_gets【自定义输入】
为满足以下几点编写自定义输入:
- 从标准输入读取数据;
- 能够指定读取字符个数;
- 丢弃换行符;
- 丢弃行缓冲区剩余数据;
char *s_gets(char *str, int n) { char *ret_var; int i = 0; ret_var = fgets(str, n, stdin); if(ret_var) { while(str[i] != '\n' && str[i] != '\0') { i++; } if(str[i] == '\n') str[i] = '\0'; else while(getchar() != '\n') continue; } return ret_var; }
使用方式
#include <stdio.h> #define STLEN 8 int main() { char words[STLEN]; while(s_gets(words, STLEN) && words[0] != '\n') // 没有输入数据会自动退出程序 { puts(words); } return 0; }
相关文章推荐
- 根据输入日期通过位移方式解决包含当月的前几月自定义函数 http://reportsoft.blog.hexun.com/75077561_d.html
- 根据输入日期通过位移方式解决包含当月的前几月自定义函数
- 根据输入日期通过位移方式解决包含当月的前几月自定义函数
- 根据输入日期通过位移方式解决包含当月的前几月自定义函数
- 根据输入日期通过位移方式解决包含当月的前几月自定义函数
- Struts2学习笔记(四)输入校验——自定义编码方式
- R语言-要点琐细及自定义函数的创建
- C 自定义输入函数
- 组合数求解公式为C……。编程序输入m,n,输出组合数,要求用自定义函数实现求阶乘
- mysql函数的创建以及hibernate调用mysql自定义函数以及数据对比功能,模仿中关村在线
- 文件输入/输出函数对比
- 对比讲解lambda表达式与传统接口函数实现方式
- 编写一个“banner”函数,该函数的输入为大写字母,输出为一个字符数组,该数组以图形化的方式表示该字母。
- 实验 9 指针1 输入一行字符,要求用自定义的函数void f(char *line)统计和输出字符串中数字字符、英文字符和其他字符的个数
- 编写一个函数,该函数的功能是在输入列表中查找所有的5的倍数,并将结果以列表方式返回
- 选择某种Map集合保存学号从1到15的学员的学号(键)和姓名(值),学号用字符串表示,输入的时候要以学号乱序的方式存入Map集合,然后按照学号从大到小的顺序将Map集合中的元素输出打印。需要自定义Ma
- 文件输入/输出函数对比
- python中使用input()函数获取用户输入值方式
- Ext为处理函数自定义输入参数的四种方法(转载)
- Hadoop3集群搭建之——hive添加自定义函数UDTF (一行输入,多行输出)