c/c++字符串输入的问题

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类的变量。

发布了44 篇原创文章 · 获赞 0 · 访问量 844

猜你喜欢

转载自blog.csdn.net/Komatsu_1137/article/details/104055354