c++开关语句出现问题

Issue with c++ switch statement

本文关键字:问题 语句 开关 c++      更新时间:2023-10-16

我在c++中遇到了一个switch语句问题。

我已经构建了一个菜单,可以在其中选择要做的各种事情,当我选择一个不需要设置任何变量的函数时,即getstat()-调用stats,它可以很好地工作。然而,每次我选择一个接受变量的函数时,代码都会完美地运行,但当它循环回来进行下一次选择时,它会停留在以前选择的函数上。

我有什么想法可以解决这个问题吗?

在下面的代码中,我检查我的统计数据(效果良好),然后选择踢球,输入所需的距离,函数踢球,然后我想选择检查距离,但当我尝试踢已经选择的球时。

我假设这与cin有关,因为其他函数没有cin,它们工作得很完美。

#include <iostream>
#include <string>
#include <windows.h>
int distance = 0;
int target;
using namespace std;
int main() {
    string Menu[3] = { "Check stats", "kick the ball", "Check distance" };
int pointer = 0;
while (true)
{
    system("cls");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
    cout << "Main Menunn";
    for (int i = 0; i < 3; ++i)
    {
        if (i == pointer)
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
            cout << Menu[i] << endl;
        }
        else
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
            cout << Menu[i] << endl;
        }
    }
    while (true)
    {
        if (GetAsyncKeyState(VK_UP) != 0)
        {
            pointer -= 1;
            if (pointer == -1)
            {
                pointer = 2;
            }
            break;
        }
        else if (GetAsyncKeyState(VK_DOWN) != 0)
        {
            pointer += 1;
            if (pointer == 4)
            {
                pointer = 0;
            }
            break;
        }
        else if (GetAsyncKeyState(VK_RETURN) != 0)
        {
            switch (pointer)
            {
            case 0:
            {
                cout << "nnnPlaying Check stats";
                cout << me.stats();
                Sleep(1000);
            } break;
            case 1:
            {
                cout << "nnn Kick the ball n how far?";
                cin >> distance; 
                target = distance;
                me.kick();
                Sleep(1000);
            } break;
            case 2:
            {
                cout << "nnnCheck distance";
                me.distance();
                Sleep(1000);
            } break;
            case 3:
            {
                return 0;
            } break;
            }
            break;
        }
    }
    Sleep(150);
}
return 0;

}

原因是在键盘上输入值后,必须按回车键(VK_RETURN)才能读取该值,并且根据MSDN上GetAsyncKeyState()函数的文档:

如果函数成功,则返回值指定键自上次调用GetAsyncKeyState以来被按下,并且键当前是向上还是向下。如果设置了最高有效位键按下,如果设置了最低有效位,则键为在上一次调用GetAsyncKeyState后按下。

这意味着,即使在上一次调用后的最后一次按键,函数调用也将返回true,因此在您按下回车键以获得cin输入后,下次您绕过else if (GetAsyncKeyState(VK_RETURN) != 0)时将为true(这次不按任何键),并要求您输入距离。。。等等…

不过,你可以这样做(无论如何,这不是实现你想要实现的目标的最佳解决方案):

int flag=1;
while (true) {
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
cout << "Main Menunn";
for (int i = 0; i < 7; ++i)
{
    if (i == pointer)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
        cout << Menu[i] << endl;
    }
    else
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
        cout << Menu[i] << endl;
    }
}
if (GetAsyncKeyState(VK_UP) != 0){
        pointer -= 1;
        if (pointer == -1)
        {
            pointer = 2;
        }
        flag=1;
        //break;//i don't know why you need this one
    }
else if (GetAsyncKeyState(VK_DOWN) != 0) {
        pointer += 1;
        if (pointer == 7)
        {
            pointer = 0;
        }
        flag=1;
        //break;//i don't know why you need this one
    }
else if (GetAsyncKeyState(VK_RETURN) != 0 && flag){
        switch (pointer) {
        case 0: cout << "nnn Call stats!";
            me.stats(); //this works perfectly and I can 
            Sleep(1000) //select a different option on the next loop.
        break;
        case 1: cout << "nnn Kick the ball n how far in meters?";
            FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
            cin >> choice; //previously defined
            flag=0;//makes the next else if(GetAsyncKeyState(VK_RETURN) != 0 && flag) false,otherwise since enter(VK_RETURN) will be pressed to get input using cin,you will enter in an endless loop which leads only to here...
            Sleep(1000);
          break;
        case 2: cout << "nnn Check distance";
            me.distance();
            Sleep(1000);
        break;
        case 3: return 0; //Exit
         break;
        }
        //break;//i don't know why you need this one
        }
        else
           flag=1;
    }
  Sleep(150);
  }