这是我使用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的解决方案
第一解决方案
当用户开始输入直到按Enter键时,不会处理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;
}