C++ getchar() 不能正常工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8442644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getchar() doesn't work well?
提问by Aan
I wrote this code in C++, and I used getchar()
to puase the console, but I did not see any effect of using that function, here is the code:
这段代码我是用C++写的,以前getchar()
是puase控制台的,但是没看到用那个函数有什么效果,代码如下:
#include<iostream>
#include<stdio.h>//to pause console screen
using namespace std;
//function prototypes
int getSmallest(int*);
int getOccurrence(int, int*);
int main(){
int a[7], counter=0, smallest;
cout<<"Please enter 7 integers"<<endl;
while(counter!=7){
cin>>a[counter];
counter++;
}
smallest=getSmallest(a);
cout<<"The smallest number is "<<smallest<<"; it apears "<<getOccurrence(smallest,a)<<" times"<<endl;
getchar();//to pause console screen
return 0;
}
int getSmallest(int*x){
int count=0, smallest=*x;
//loop till last item in array
while(count!=7){
if(*x<smallest)
smallest=*x;
count++;
x++;
}
return smallest;
}
int getOccurrence(int smallest, int* address){
int count=0,occ=0;
//loop till last item in array
while(count!=7){
if(*address==smallest)
occ++;
count++;
address++;
}
return occ;
}
回答by HostileFork says dont trust SE
As has been pointed out, the issue is that your input buffer had a string for the number AND a newline. C++ I/O skips leading whitespace when it reads something like a number out, but it doesn't take the trailing whitespace out of the buffer. It leaves that for the nextread to deal with. So getchar()
is getting that newline that's still pending.
正如已经指出的那样,问题在于您的输入缓冲区有一个数字字符串和一个换行符。C++ I/O 在读取数字之类的内容时会跳过前导空格,但不会从缓冲区中取出尾随空格。它将留给下一次阅读来处理。所以getchar()
越来越即换行符是仍然悬而未决。
Ignore advice from people who are trying to tell you to flush(), ignore(), or clear out "whatever was in the buffer before the getchar()
call". These functions have no notions of "non-blocking" input.
忽略那些试图告诉你flush()、ignore()或清除“getchar()
调用前缓冲区中的任何内容”的人的建议。这些函数没有“非阻塞”输入的概念。
Said another way: the usual C++ input stream functions don't have a concept of "there's nothing there right now"...but then you call later and it says "oh, but nowthere's something!!!"There's an "input sequence" that you can only detect as stopping when you hit EOF.
换一种方式说:通常的 C++ 输入流函数没有“现在什么都没有”的概念......但是你稍后调用它会说“哦,但现在有东西!!!” 有一个“输入序列”,您只能在点击 EOF 时将其检测为停止。
The exception to this would be readsome()...which rather than operating on an "input sequence" operates on the "input buffer". Finding such a thing, we might try this:
对此的例外是readsome()...它不是对“输入序列”进行操作,而是对“输入缓冲区”进行操作。找到这样的东西,我们可以试试这个:
#include<iostream>
#include<cstdio>//to pause console screen
using namespace std;
int main(int argc, char* argv[]) {
cout << "Enter a number\n";
int num;
cin >> num;
char ch;
while (cin.readsome(&ch, 1) != 0)
;
cout << "Press any key to continue...\n";
getchar();
return 0;
}
But at least on my machine, it doesn't lead to the desired effect. Which means that even though there's a newline sitting in the terminal app or OS pipeline somewhere, it hasn't yet gotten as far as the internal stream buffer object for cin
. Upshot is: there is a non-blocking input function based on the buffer, but in this kind of scenario it apparently isn't going to help.
但至少在我的机器上,它并没有达到预期的效果。这意味着即使在终端应用程序或操作系统管道中的某个地方有一个换行符,它也没有达到cin
. 结果是:有一个基于缓冲区的非阻塞输入函数,但在这种情况下,它显然无济于事。
The realanswer is what Alf said in the comment. Most decent dev environments or setups will have some way to configure it to not let the console close automatically. If not, hack around it with your launch method. Heck, you can even put a breakpoint on the return 0
in main!
在真正的答案是什么阿尔夫在评论说。大多数体面的开发环境或设置都会有一些方法来配置它不让控制台自动关闭。如果没有,请使用您的启动方法绕过它。哎呀,你甚至可以return 0
在 main上放置一个断点!
Notes:
笔记:
You should be aware that "correct" C++ inclusions of compatibility libraries for C are done as #include <cfoo>
instead of #include "foo.h"
. It may not make all that big a difference in practice...but at minimum it distracts from your question when people comment about it (like I'm doing right now):
您应该知道,C 的兼容性库的“正确”C++ 包含是作为#include <cfoo>
而不是#include "foo.h"
. 它在实践中可能不会产生太大的差异......但至少当人们评论它时它会分散你的问题(就像我现在正在做的那样):
在 C++ 中使用 C 头文件而不是等效的 C++ 头文件(例如 stdio.h 而不是 cstdio)是不好的做法吗?
Also, you could have demonstrated this with a much smaller sample! You could have shown the effect simply with:
此外,您可以用更小的样本来证明这一点!您可以简单地显示效果:
#include<iostream>
#include<cstdio>//to pause console screen
using namespace std;
int main(int argc, char* argv[]) {
cout << "Enter a number\n";
int num;
cin >> num;
cout << "Press any key to continue...\n";
getchar();
return 0;
}
So try and pare down your examples to really isolate the problem in the future! (Feel free to edit your question to be this succinct in order to make this thread more useful for people searching.)
因此,尝试减少您的示例以在将来真正隔离问题!(随意编辑您的问题以使其简洁,以使该线程对人们进行搜索更有用。)
回答by Hemant Metalia
It may be the problem of the buffer. Because of buffer the getChar takes input from buffer so it will better to flush buffer
before calling getChar()
可能是缓冲区的问题。由于缓冲区,getChar 从缓冲区获取输入,因此最好flush buffer
在调用 getChar() 之前
回答by vdsf
Try this:
尝试这个:
int main()
{
// ...
std::cin.get();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return 0;
}
回答by Taha
Here are the two alternates:
这是两个替代方案:
getch();
you will have to use#include <conio.h>
- system("pause");
getch();
你将不得不使用#include <conio.h>
- 系统(“暂停”);
回答by geneemailbox1 geneemailbox1
thats why they put isspace and ispunct functions in your own function prototypes and have pointers to values b/c cin>> and "while((ch = getchar()) != '\n')" are fpermissive most get away with it is using a pointer and size t which is the return type of the Cstrings function "strlen()"
这就是为什么他们把 isspace 和 ispunct 函数放在你自己的函数原型中,并有指向值的指针 b/c cin>> 和 "while((ch = getchar()) != '\n')" 是 fpermissive 大多数摆脱它正在使用指针和大小 t,它是 Cstrings 函数“strlen()”的返回类型
void remove_whitespace(char *str)
{
char *p;
size_t len = strlen(str);
for(p = str; *p; p ++, len --) {
while(isspace(*p)) memmove(p, p+1, len--);
}
for the c programming example ... here
对于 c 编程示例...这里
char string[100], ch;
int i = 0;
cout<<"Enter a message: ";
while((ch = getchar()) != '\n') //grab users input string untill
{ //Enter is pressed
if (!isspace(ch) && !ispunct(ch)) //Cstring functions checking for
{
string[i] = tolower(ch);
i++;
}
}
if you want to write only c++ code you have to make your own functions from scratch... or try to use terrible functions that have *'s in them
如果您只想编写 C++ 代码,则必须从头开始制作自己的函数……或者尝试使用带有 * 的糟糕函数
char name[100];
//string userInput[26];
int i=0, n=0;
cout<<"your name? ";
cin>>name;
cout<<"Hello "<<name<< endl;
char *ptr=name;
for (i = 0; i < 20; i++)
{
cout<<i<<" "<<ptr[i]<<" "<<(int)ptr[i]<<endl;
}
int length = 0;
while(name[length] != '##代码##')
{
length++;
}
cout<<name <<"is"<<length<<"chars long"