如何模拟“按任意键继续?”

时间:2009-09-19 19:35:50

标签: c++

我正在尝试编写一个C ++程序,当用户从键盘输入任何字符时,它应移动到下一行代码。

这是我的代码:

char c;

cin>>c;

cout<<"Something"<<endl;

但这不起作用,因为当我输入一些字符然后按ENTER键时它只会移动到下一行。

OR

如果我使用这个

cin.get() or cin.get(c)

当我按Enter键时,它会转到下一行指令。

但我希望它能够在键盘上按下的任何键上移动到下一行,如何做到这一点?

15 个答案:

答案 0 :(得分:55)

在Windows上:

system("pause");

在Mac和Linux上:

system("read");

将输出“按任意键继续...”,显然,等待按任何键。 我希望那就是你的意思

答案 1 :(得分:51)

如果您使用的是Windows,则可以使用kbhit(),它是Microsoft运行时库的一部分。如果您使用的是Linux,则可以实现kbhitsource):

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

更新:以上功能适用于OS X(至少在OS X 10.5.8 - Leopard上,所以我希望它可以在更新版本的OS X上运行)。此gist可以保存为kbhit.c,并使用

在Linux和OS X上进行编译
gcc -o kbhit kbhit.c

使用

运行时
./kbhit

它会提示您按键,并在按键时退出(不限于Enter键或可打印键)。

@Johnsyweb - 请详细说明“详细规范答案”和“所有问题”的含义。此外,重新“跨平台”:使用kbhit()的这种实现,您可以在Linux / Unix / OS X / Windows上的C ++程序中具有相同的功能 - 您可能指的是其他平台?

@Johnsyweb的进一步更新: C ++应用程序并不存在于密封的C ++环境中。 C ++成功的一个重要原因是与C的互操作性。所有主流平台都是用C接口实现的(即使内部实现使用的是C ++),所以你对“遗留”的讨论似乎不合适。另外,在我们讨论单个函数时,为什么需要C ++(“C with classes”)?正如我所指出的,您可以使用C ++编写并轻松访问此功能,而您的应用程序的用户不太可能关心 您实现它的方式。

答案 2 :(得分:7)

没有完全可移植的解决方案。

comp.lang.c FAQ的问题19.1在某种程度上涵盖了这一点,包括Windows,类Unix系统甚至MS-DOS和VMS的解决方案。

快速且不完整的摘要:

  • 您可以使用curses库;调用cbreak()后跟getch()(不要与Windows特定的getch()函数混淆)。请注意,curses通常会控制终端,因此这可能会过度。
  • 您可以使用ioctl()来操作终端设置。
  • 在符合POSIX标准的系统上,tcgetattr()tcsetattr()可能是更好的解决方案。
  • 在Unix上,您可以使用system()来调用stty命令。
  • 在MS-DOS上,您可以使用getch()getche()
  • 在VMS(现在称为OpenVMS)上,屏幕管理(SMG$)例程可能会起作用。

所有这些C解决方案在C ++中应该同样有效;我不知道任何特定于C ++的解决方案。

答案 3 :(得分:6)

要实现此功能,您可以使用ncurses库,该库在Windows和Linux(以及据我所知的MacOS)上实现。

答案 4 :(得分:5)

这很简单。 我制作了一个程序,它的工作非常完美......这就是程序。

#include<iostream.h>
#include<conio.h>

void  check()
{
    char chk; int j;
    cout<<"\n\nPress any key to continue...";
    chk=getch();
    j=chk;
    for(int i=1;i<=256;i++)
      if(i==j) break;
    clrscr();
}

void main()
{
    clrscr();
    check();
    cout<<"\n\nSee, Its Working....Have a Good day";
    getch();
}

答案 5 :(得分:4)

我调查了你想要实现的目标,因为我记得我想做同样的事情。灵感来自Vinay我写了一些对我有用的东西,我有点理解。但我不是专家,所以请小心。

我不知道Vinay是如何知道您使用的是Mac OS X.但它应该与大多数类似Unix的操作系统一样。资源非常有用opengroup.org

确保在使用该功能之前冲洗缓冲区。

#include <stdio.h>
#include <termios.h>        //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>     //STDIN_FILENO


void pressKey()
{
    //the struct termios stores all kinds of flags which can manipulate the I/O Interface
    //I have an old one to save the old settings and a new 
    static struct termios oldt, newt;
    printf("Press key to continue....\n");

    //tcgetattr gets the parameters of the current terminal
    //STDIN_FILENO will tell tcgetattr that it should write the settings
    // of stdin to oldt
    tcgetattr( STDIN_FILENO, &oldt);
    //now the settings will be copied 
    newt = oldt;

    //two of the c_lflag will be turned off
    //ECHO which is responsible for displaying the input of the user in the terminal
    //ICANON is the essential one! Normally this takes care that one line at a time will be processed
    //that means it will return if it sees a "\n" or an EOF or an EOL
    newt.c_lflag &= ~(ICANON | ECHO );      

    //Those new settings will be set to STDIN
    //TCSANOW tells tcsetattr to change attributes immediately. 
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    //now the char wil be requested
    getchar();

    //the old settings will be written back to STDIN
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

}


int main(void)
{
  pressKey();
  printf("END\n");
  return 0;
}

O_NONBLOCK似乎也是一个重要的旗帜,但它并没有为我改变任何东西。

如果有更深入知识的人会对此发表评论并提出一些建议,我将不胜感激。

答案 6 :(得分:4)

您可以使用Microsoft特定的功能_getch

#include <iostream>
#include <conio.h>
// ...
// ...
// ...
cout << "Press any key to continue..." << endl;
_getch();
cout << "Something" << endl;

答案 7 :(得分:3)

适用于Windows平台: 它直接使用微处理器寄存器,可用于检查按键或鼠标按钮

    #include<stdio.h>
    #include<conio.h>
    #include<dos.h>
    void main()
    {
     clrscr();
     union REGS in,out;
     in.h.ah=0x00;
     printf("Press any key : ");

     int86(0x16,&in,&out);
     printf("Ascii : %d\n",out.h.al);
     char ch = out.h.al;
     printf("Charcter Pressed : %c",&ch);
     printf("Scan code : %d",out.h.ah);
     getch();
    }

答案 8 :(得分:2)

如果您使用的是Visual Studio 2012或更早版本,请使用&#34; getch()&#34;函数,如果您使用的是Visual Studio 2013或更高版本,请使用&#34; _getch()&#34;。您必须使用&#34; #include&lt; conio.h&gt;&#34;。例如:

#include "stdafx"
#include <iostream>
#include <conio.h>

int main()
{
   std::cout << "Press any key to continue. . .\n"
   _getch() //Or "getch()"
}

答案 9 :(得分:1)

您可以使用getchar例程。

从以上链接:

/* getchar example : typewriter */
#include <stdio.h>

int main ()
{
  char c;
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");
  do {
    c=getchar();
    putchar (c);
  } while (c != '.');
  return 0;
}

答案 10 :(得分:0)

您也可以使用conio.h中的getch()。 就像这样:

...includes, defines etc
void main()
{
//operator
getch(); //now this function is waiting for any key press. When you have pressed its     just     //finish and next line of code will be called
}

所以,因为UNIX没有conio.h,我们可以通过这段代码模拟getch()(但这段代码已经由Vinary编写,我的失败):

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch( ) {
  struct termios oldt,
             newt;
  int            ch;
  tcgetattr( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
  return ch;
}

答案 11 :(得分:0)

另一种选择是使用 threads with function pointers

#include <iostream>
#include <thread> // this_thread::sleep_for() and thread objects
#include <chrono> // chrono::milliseconds()

bool stopWaitingFlag = false;

void delayms(int millisecondsToSleep) 
{
  std::this_thread::sleep_for(std::chrono::milliseconds(millisecondsToSleep));
}

void WaitForKey() 
{
  while (stopWaitingFlag == false)
  {
    std::cout<<"Display from the thread function"<<std::endl;
    delayms(1000);
  }
}

 

int main()
{
  std::thread threadObj(&WaitForKey);

  char userInput = '\0';
  while (userInput != 'y')
  {
    std::cout << "\e[1;31mWaiting for a key, Enter 'y' for yes\e[0m" << std::endl;
    std::cin >> userInput;
    if (userInput == 'y') {
      stopWaitingFlag = true;
    }
  }
  if (threadObj.joinable())
    threadObj.join();

  std::cout<<"Exit of Main function"<<std::endl;
  return 0;
}

答案 12 :(得分:-1)

#include <iostream>
using namespace std;

int main () {
    bool boolean;
    boolean = true;

    if (boolean == true) {

        cout << "press any key to continue";
        cin >> boolean;

    }
    return 0;
}

答案 13 :(得分:-2)

如果你现在在MSDN上查找kbhit()函数,它表示该函数已被弃用。改为使用_kbhit()。

#include <conio.h>
int main()
{
    _kbhit();
    return 0;
}

答案 14 :(得分:-4)

只需使用system("pause");命令即可​​。

所有其他答案都使问题复杂化。