POJ2236 Wireless Network
做这道题时遇到了一点小麻烦,声明了一个char型变量ch,循环输入以后发现不能正常输出,参考了别人的题解以及查阅了资料以后总结出了一些关于c/c++输入问题。
先贴一个代码:
#include <stdio.h>
int main() {
char ch;
while(~scanf("%c", &ch)) {
if(ch == 'O')
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
运行结果:
O
YES
NO
1
NO
NO
为什么会出现这样的结果呢?
是因为scanf读取字符时,同样会读取到空白字符(回车,空格,制表符)。上述程序输入O并且点击回车键,scanf会从缓冲区读取字符O,但回车键即换行符还留在缓冲区,此时输出YES并换行,但是scanf会立即读取到上次输入时留在缓冲区的换行符并输出NO。相当于执行一次输入,循环了两次(scanf分别读取输入的字符和换行符)。
首先我们能这样写:
#include <stdio.h>
int main() {
char ch;
while(~scanf("%c", &ch)) {
if(ch == '\n')
continue;
if(ch == 'O')
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
可以正常输出。
也可以这样:
#include <stdio.h>
int main() {
char ch[2];
while(~scanf("%s", ch)) {
if(ch[0] == 'O')
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
getchar()和fflush()
#include <stdio.h>
int main() {
char ch;
while(~scanf("%c", &ch)) {
//getchar();
fflush(stdin);
if(ch == 'O')
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
getchar()吸收一个多余的缓冲区内的回车。
fflush()的作用是清空缓冲区,fflush(stdin)和fflush(stdout)分别可以清除标准输入和输出的缓冲区。
两个函数都可以使得程序运行正常的结果。
" %c"
#include <stdio.h>
int main() {
char ch;
while(~scanf(" %c", &ch)) {
if(ch == 'O')
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
这里的 %c 前面有一个空格,查阅了资料以后发现了这个神奇的用法,如果 %c 前面有空格那么会直接忽略掉缓冲区的空格和回车(亲测无论输入多少个空格和回车都可以正常输出)。
除此之外还注意到一个知识点,"%*c"可以忽略一个char型字符,即不给变量赋值。
gets()
#include <stdio.h>
int main() {
char ch[2];
while(gets(ch)) {
if(ch[0] == 'O')
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
gets()函数可以读取一行字符串,与scanf("%s")的不同之处在于scanf("%s")读取字符串遇到空白字符就停了,但gets()函数读取的字符串可以有空格。
另外gets()函数读取字符串时会将缓冲区内的回车字符取出并丢弃,也就是说最后缓冲区内是没有多余的回车的。
关于c++的输入
之前在写二叉树建立的代码时,前序建立二叉树,输入用的是cin,控制台输入空格表示一棵空子树,结果不能正常运行。后来才知道cin是不能读取空格的,而cin.get()读取一个字符,该字符可以是空格。
读取一行字符串,可以用getline(),语法为getline(cin, str),其中str为string类的变量。