关于 输入
时间:2010-05-28 来源:chhaya
写了这么久的C,这几天做了几个模拟题,才发现自己对于scanf输入都还不怎么了解,主要是输入字符和字符串。
看了网上两篇文章,再结合以前看的《现代方法》, 总结一些东西:
1. scanf返回并赋值给实参的数据项数量, 如果读取之前就失败,返回EOF。 惯用法:while(scanf("%d", &n) == 1) {} 2. scanf类函数格式串中的一个或多个连续的空白字符匹配零个或多个输入流中的空白字符。 3. %s 匹配一序列非空白字符,然后在末尾添加空字符 %[ 匹配来自集合的非空字符序列,然后在末尾添加空字符 %c 匹配一个字符,在末尾添加空字符 scanf(" %c %c", &a, &b); 输入'MN' 或者'M N' 或者' MN'都会把M给a,N给b. 4. %[abc] 匹配含有只含有a,b,c的任何字符串; %[^abc] 匹配不含a,b,c的任何字符串,当遇到a,b,c时结束输入。 所以用scanf("%[^\n]", str) 可以输入整行的字符,包括中间的空格, 除了最后的回车符没读进去。
5. scanf读入并存储了n个数据项, 那么希望它的返回值是n, 如果小于n,那肯定是错了,有三种情况: (1) 文件末尾。在完全匹配格式串之前遇到了文件末尾。 (2) 错误。 错误的发生超出了函数控制范围 (3) 匹配失败。 数据项的格式是错误的。
6.曾经有看到过fflush(stdin)来清空输入缓冲区, 我今天试了下,发现没用, 后来看到"The function fflush() forces a write of all user-space buffered data for the given output or update stream via the stream’s underlying write
function. " 原来fflush是给输出流和更新流用的, 没有给输入流用,所以fflush(stdin)是不对的。 有的地方能用是那些编译器(如VC6.0)支持,也只是对C标准的一个扩充。 所以我用GCC编译就没用啦。 想了解更多关于fflush的看这篇文章,讲得很不错, 还有一个可行的清空输入流的方法:http://stdcpp.cn/html/3/3/0510/6.htm
还有几个经常搞不零清的输入输出字符和字符串的函数: int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void);
功能都一样,读入一个字符,不同之处在于: #define getchar() getc(stdin) 从文件中读取字符串的话,用getc 胜过 fgetc, 因为getc是宏,fgetc是函数,所以getc更快。 三个函数读到文件末尾都会返回EOF, 惯用法: while((ch = getc(fp)) != EOF) {} 还有这三个函数返回的都是int型的,所以要把返回值存储在int变量中,否则在跟EOF比较时可能会有问题
最后一个: gets(str); 逐个读取字符,并且把它们存储在字符串中, 直到它读到换行符时停止,且会丢失此换行符.这就跟scanf("%[^\n]", str)的功能一样了。 而scanf("%s", str)的跟它们不同的地方在于它从非空字符开始读,直到遇到空字符。 用gcc编译的时候,总是警告gets不安全, 要么忽略了,要么用更强大的fgets吧,
好了,暂时总结到这里,以后遇到再添加, 基本上都明白了, 用这些把1684搞定去!
如果有人看到发现错误请指出,谢谢。
1. scanf返回并赋值给实参的数据项数量, 如果读取之前就失败,返回EOF。 惯用法:while(scanf("%d", &n) == 1) {} 2. scanf类函数格式串中的一个或多个连续的空白字符匹配零个或多个输入流中的空白字符。 3. %s 匹配一序列非空白字符,然后在末尾添加空字符 %[ 匹配来自集合的非空字符序列,然后在末尾添加空字符 %c 匹配一个字符,在末尾添加空字符 scanf(" %c %c", &a, &b); 输入'MN' 或者'M N' 或者' MN'都会把M给a,N给b. 4. %[abc] 匹配含有只含有a,b,c的任何字符串; %[^abc] 匹配不含a,b,c的任何字符串,当遇到a,b,c时结束输入。 所以用scanf("%[^\n]", str) 可以输入整行的字符,包括中间的空格, 除了最后的回车符没读进去。
5. scanf读入并存储了n个数据项, 那么希望它的返回值是n, 如果小于n,那肯定是错了,有三种情况: (1) 文件末尾。在完全匹配格式串之前遇到了文件末尾。 (2) 错误。 错误的发生超出了函数控制范围 (3) 匹配失败。 数据项的格式是错误的。
6.曾经有看到过fflush(stdin)来清空输入缓冲区, 我今天试了下,发现没用, 后来看到"The function fflush() forces a write of all user-space buffered data for the given output or update stream via the stream’s underlying write
function. " 原来fflush是给输出流和更新流用的, 没有给输入流用,所以fflush(stdin)是不对的。 有的地方能用是那些编译器(如VC6.0)支持,也只是对C标准的一个扩充。 所以我用GCC编译就没用啦。 想了解更多关于fflush的看这篇文章,讲得很不错, 还有一个可行的清空输入流的方法:http://stdcpp.cn/html/3/3/0510/6.htm
还有几个经常搞不零清的输入输出字符和字符串的函数: int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void);
功能都一样,读入一个字符,不同之处在于: #define getchar() getc(stdin) 从文件中读取字符串的话,用getc 胜过 fgetc, 因为getc是宏,fgetc是函数,所以getc更快。 三个函数读到文件末尾都会返回EOF, 惯用法: while((ch = getc(fp)) != EOF) {} 还有这三个函数返回的都是int型的,所以要把返回值存储在int变量中,否则在跟EOF比较时可能会有问题
最后一个: gets(str); 逐个读取字符,并且把它们存储在字符串中, 直到它读到换行符时停止,且会丢失此换行符.这就跟scanf("%[^\n]", str)的功能一样了。 而scanf("%s", str)的跟它们不同的地方在于它从非空字符开始读,直到遇到空字符。 用gcc编译的时候,总是警告gets不安全, 要么忽略了,要么用更强大的fgets吧,
好了,暂时总结到这里,以后遇到再添加, 基本上都明白了, 用这些把1684搞定去!
如果有人看到发现错误请指出,谢谢。
相关阅读 更多 +