C++ 如何使用 ESC 按钮终止我的程序

2023-12-05

这是我的主要功能,我使用 Visual Studio 2012 Express,代码工作正常。我的问题是,当用户按下 ESC 按钮而不是 -1 时,我将如何终止此循环。虽然我更喜欢在 UNIX 和 Windows 上都可以使用的解决方案,但如果不可能的话,我最感兴趣的是它在 Windows 上的工作。

int _tmain(int argc, _TCHAR* argv[])
{
list mylist;

int value;
cout<<"Give the numbers you want to insert to the list, press -1 to stop\n";
do
{
    cin>>value;
    mylist.insertf(value);
    mylist.sort_list();
    mylist.print();
}while(value!=-1);




}

以下是 Windows 的解决方案

第一个解决方案:

当用户开始输入直到按下回车键时,Esc 不会被处理。 空闲时 Esc 将被处理

#include <Windows.h>
#include <iostream>
#include <conio.h>
#include <vector>
int main(int argc, char **argv)
{
    int value=0;
    std::vector<int> mylist; 
    do
    {   
        //check if any input.
        if (_kbhit()){
            //probable user started to type 
            //block to read till the user press Enter. If you want to handle Esc here .
            //then you should manually do input reading . I will write that solution later
            std::cin>>value; 
            //if success
            if(std::cin.good()){ 
                mylist.push_back(value); 
            }else{
                //firstly, clear error flag 
                std::cin.clear();
                //ignore 
                std::cin.ignore(10000,'\n');

            }

            //print  list
            std::cout<<"new list: { " ;
            for(int i=0;i< mylist.size();i++){
                std::cout<<mylist[i]<<'\t';
            }
            std::cout<<" }"<<std::endl;
        }

        //check if Esc Pressed
    }while(GetAsyncKeyState(VK_ESCAPE)==0);

    return 0;
}

第二种解决方案:

Esc 将始终在另一个线程中处理。在某些情况下,立即退出可能是不可取的

DWORD WINAPI CheckEscape( LPVOID lpParam ) {
        while(GetAsyncKeyState(VK_ESCAPE)==0){
            //sleep 
            Sleep(10);
        }
        exit(0);

}



int main(int argc, char **argv)
{
    int value=0;
    std::vector<int> mylist; 
    //create thread for handling ESC key
    CreateThread( NULL, 0, CheckEscape,NULL  , 0, NULL);

    //loop infinitely
    while(true)
    {    
            std::cin>>value; 
            //if success
            if(std::cin.good()){ 
                mylist.push_back(value); 
            }else{
                //firstly, clear error flag 
                std::cin.clear();
                //ignore 
                std::cin.ignore(10000,'\n');

            }

            //print  list
            std::cout<<"new list: { " ;
            for(int i=0;i< mylist.size();i++){
                std::cout<<mylist[i]<<'\t';
            }
            std::cout<<" }"<<std::endl;
        }  
    return 0;
}

第三种解决方案和最好的.手动完成所有操作

手动处理按键。 当按下 Esc 时将调用 Exit。您可以更改它以处理更正确的方式

bool keypress( char &key){
    INPUT_RECORD IR[1];
    DWORD read;
    static HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
    while(PeekConsoleInputA(h,IR,1,&read)){
        if(read!=0){
            //check if it was Key Event
            if(IR[0].EventType==KEY_EVENT){
                key=IR[0].Event.KeyEvent.uChar.AsciiChar; 
                ReadConsoleInputA(h,IR,1,&read);
                FlushConsoleInputBuffer(h);
                return true;
            }
            if(ReadConsoleInputA(h,IR,1,&read)){
                continue; 
            }
        }else{
            return false;
        }
    }
}

//getnumber
int cinnumb( ){
    char buffer[32];
    buffer[0]='\0';
    int count=0;
    DWORD key=-1;
    while(true){

        Sleep(100);
        do{
            //here I make it nonblockin keypress
            //but actually we do not need it 
            //we can use blocking ReadConsoleInputA(h,IR,1,&read);
            //this way we not even need sleep() and 
            //our keypress function will be simple
            //anyway im posting nonblocking one

            //nonblocking keypress
            char key=0;
            bool isOk=keypress(key );

            if(!isOk ){ 
                Sleep(20);
                continue;
            }

            if(key>='0' && key<='9'){
                buffer[count]=key; 
                std::cout<<key;
                ++count;
                if( count==31)break;

            }

            // check Enter key and  enough symbol
            if(  key==13 && count>0  ){  
                std::cout<<std::endl;
                break;
            }

            //for windows 

            //check if Esc pressed
            if(key==27) exit(0); 


        }while(true);

        buffer[count]='\0';

        int value=atoi(buffer);
        return value;
    }
}
int main(int argc, _TCHAR* argv[])
{
    std::vector<int> mylist; 
    int value; 
    char buffer[100];
    //infinite loop
    while(true)
    {   
        //get number 
        value=cinnumb(); 
        mylist.push_back(value);
         //print  list
        std::cout<<"new list: { " ;
        for(int i=0;i< mylist.size();i++){
                std::cout<<mylist[i]<<'\t';
            }
        std::cout<<" }"<<std::endl;
        //sleep a little
        Sleep(10); 
    } ;


    return 0;

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 如何使用 ESC 按钮终止我的程序 的相关文章

  • 使用 gcc 的中间 GIMPLE 格式

    根据本文 http en wikipedia org wiki Intermediate languagegcc 在生成代码之前使用多种中间格式 我读到 GIMPLE 格式使用三个地址代码 这似乎是最容易使用的中间语言 但我需要更多细节 因
  • 来自 RAZOR 中不同文件夹的 RenderPartial

    我一直在尝试将我的 aspx 页面转换为 cshtml 并且在从另一个文件夹渲染部分页面时遇到问题 我以前做过的事 我认为等价的是 Html RenderPartial Views Inquiry InquiryList cshtml Mo
  • codecvt 不是 std 标头吗?

    此代码使用 Visual C 11 进行编译 并在 Windows 7 上按预期运行 但无法使用 Windows 7 上的 MinGW 4 7 0 或 Linux 上的 gcc 4 8 0 进行编译 编译用 std c 11 flag in
  • 为什么调用 istream::tellg() 会影响我的程序的行为?

    我正在尝试将 24 位位图图像转换为灰度图像 include
  • ToLookup 是否强制立即执行序列

    我正在调查可枚举 ToLookup将可枚举序列转换为字典类型数据结构的 API 更多详情可在这找到 https msdn microsoft com en us library system linq enumerable tolookup
  • Request.Url.Port 给出错误的端口

    我的支持团队为我提供了一个 Live IP 例如http 201 121 152 168 68 现在在正常情况下你会认为68是端口 但是 当我执行 Request Host 时 我得到201 121 152 168当我执行 Request
  • 时间:2019-03-17 标签:c++rapidjson返回值

    我在我的项目中使用rapidjson 我有一个方法可以解析 json 并返回其中的一部分 static rapidjson Document getStructureInfo std string structureType rapidjs
  • Windows 10 ScrollIntoView() 不会滚动到列表视图中间的项目

    我有一个包含 20 个项目的列表视图 我想以编程方式滚动列表视图 ListView ScrollIntoView ListView Items 0 将滚动列表视图到第一项 ListView ScrollIntoView ListView I
  • 私有方法和属性的 JetBrains Rider C# 命名风格

    我想将私有方法的首字母设为小写 将公共方法的首字母设为大写 然而 在 Rider 中 C 命名风格下似乎只有一个选项可以应用所有方法 属性和事件 告诉 Rider 仅对私人使用不同约定的最佳方式是什么 也可以看看 私有方法和属性的 ReSh
  • 结构体前向声明编译失败

    我有以下代码 但编译器说 sender wrapper 未定义 即使我向前声明了它 我不能对结构进行前向声明吗 用VS2003编译 struct send wrapper struct IPSend IPSend IPSend const
  • Fluent NHibernate 一对一映射

    我很难利用 Fluent NHibernate 的 HasOne 映射 基本上 A 类在 B 类中可以有匹配的 只有一条或没有 记录 请帮助定义关系的 AMap 和 BMap 类 谢谢 public class A public virtu
  • 使用事件处理程序与覆盖事件触发方法

    我正在创建 Button 的子类 并希望向其某些事件 例如 OnClick 添加自定义功能 哪种方式更理想 我是否重写 OnClick protected override void OnClick EventArgs e base OnC
  • Qt 信号槽,新符号中的转换类型[重复]

    这个问题在这里已经有答案了 鉴于以下两个 connect ui gt comboBox SIGNAL activated QString ps SLOT requestPlotsAvailable QString connect ui gt
  • 如何使用 html 敏捷包获取自定义标签?

    需要创建摘要 索引 为此我有标签
  • 将 JSON 转换为数据表

    我有以下格式的 JSON id 10 name User add false edit true authorize true view true id 11 name Group add true edit false authorize
  • 如何只应用一种 clang-format 操作?

    我想用clang 格式调整我的评论 但仅此而已 选项是 AlignTrailingComments bool 但是当我运行以下命令时 clang format 3 6 i style AlignTrailingComments true
  • 文件/文件夹结构的递归搜索

    我正在尝试为返回文件和文件夹列表的 Web 服务构建递归搜索功能 我创建了这两个方法 因此它们充当递归搜索 它首先获取顶级内容 然后将任何文件添加到 fileList 并将任何子文件夹添加到 subFoldersList 我们传入访问级别
  • 虚拟继承 - 跳过构造函数

    我有以下课程 class Socket Socket Socket SOCKET s class Connection public virtual Socket Connection IP ip 这两个类包含一些纯虚函数和一些非虚函数以及
  • C 中的静态和外部内联函数[重复]

    这个问题在这里已经有答案了 我正在尝试详细了解静态函数和外部函数之间的区别 我知道静态内联函数和外部内联函数之间的基本区别 我的理解如有错误请指正 静态内联函数仅对定义它的翻译单元可见 外部内联函数可以在多个翻译单元中访问 最好在头文件中定
  • 警告 C4172:返回局部变量或临时变量的地址[重复]

    这个问题在这里已经有答案了 可能的重复 指向局部变量的指针 https stackoverflow com questions 4570366 pointer to local variable 我在这个网站上阅读了很多关于同一问题的其他主

随机推荐