简体   繁体   English

getchar()不能正常工作?

[英]getchar() doesn't work well?

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()来创建控制台,但是使用该函数没有任何效果,下面是代码:

#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;

}

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. C ++ I / O在读取数字之类的内容时会跳过前导空白,但不会将尾随空白移出缓冲区。 It leaves that for the next read to deal with. 它留给下次阅读处理。 So getchar() is getting that newline that's still pending. 因此, 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". 忽略试图告诉您flush(),ignore()或清除“ getchar()调用之前缓冲区中的内容”的人员的建议。 These functions have no notions of "non-blocking" input. 这些功能没有“非阻塞”输入的概念。

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 now there's something!!!" 换句话说:普通的C ++输入流函数没有“现在没有东西”的概念……但是随后您调用它并说“哦,但是现在有东西!!” There's an "input sequence" that you can only detect as stopping when you hit EOF. 只有当您按下EOF时,您才能检测到“输入序列”已停止。

The exception to this would be readsome() ...which rather than operating on an "input sequence" operates on the "input buffer". 例外是readsome() ...它不是在“输入序列”上运行,而是在“输入缓冲区”上运行。 Finding such a thing, we might try this: 找到这样的东西,我们可以试试看:

#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 . 这意味着即使终端应用程序或OS管道中有换行符,也尚未到达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. 结果是:基于缓冲区有一个非阻塞输入函数,但是在这种情况下,它显然无济于事。

The real answer 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! 哎呀,您甚至可以在main的return 0上设置一个断点!


Notes: 笔记:

You should be aware that "correct" C++ inclusions of compatibility libraries for C are done as #include <cfoo> instead of #include "foo.h" . 您应该意识到,针对C的兼容性库的“正确” C ++包含项是通过#include <cfoo>而不是#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): 在实践中,这可能并没有太大的不同...但是,至少在人们对此发表评论时,这会分散您的问题(例如我现在正在做的事情):

Is it bad practice to use a C header instead of its C++ equivalent in C++ (eg stdio.h instead of cstdio)? 在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.) (请随意编辑您的问题,以使其简洁明了,以使该主题对搜索的人更有用。)

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')”的指针最容易使人困惑的原因正在使用指针和大小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] != '\0')
{
    length++;
}
cout<<name <<"is"<<length<<"chars long"

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从缓冲区获取输入,因此最好在调用getChar()之前flush buffer

Try this: 尝试这个:

int main()
{
   // ...
   std::cin.get();
   std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

   return 0;
}

Here are the two alternates: 这是两个替代方案:

  1. getch(); you will have to use #include <conio.h> 您将必须使用#include <conio.h>
  2. system("pause"); 系统(“暂停”);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM