【问题标题】:Check out my C++ Scrolling Menu and give any tips查看我的 C++ 滚动菜单并提供任何提示
【发布时间】:2014-10-11 17:03:57
【问题描述】:

现在我有一个可用的滚动菜单,我只是想问是否有人提供如何压缩它的提示,因为它有点“CHUNKY”!
另外我还有两个额外的问题:如何为我的
“摇滚,
纸,
剪刀"
像“Rock, Paper”, Scissors“一样显示?如果你试试我的代码,你会看到文本都是垂直的,我可以让它全部水平吗?有没有什么技巧可以让它变成一个 void 语句可以多次使用?

#include <iostream>
#include <string>
#include <windows.h>

using namespace std;

int main()
{
string Menu[3] = {"Rock", "Paper", "Scissors"};
int pointer = 0;

while(true)
{
    system("cls");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
    cout << "Main Menu\n\n";

    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 == 3)
            {
                pointer = 0;
            }
            break;
        }
        else if (GetAsyncKeyState(VK_RETURN) != 0)
        {
            switch (pointer)
            {
                case 0:
                {
                    cout << "\n\n\nStarting new game...";
                    Sleep(1000);
                } break;
                case 1:
                {
                    cout << "\n\n\nThis is the options...";
                    Sleep(1000);
                } break;
                case 2:
                {
                    return 0;
                } break;
            }
            break;
        }
    }

    Sleep(150);
}

return 0;
}

【问题讨论】:

  • &lt;&lt; endl; 添加换行符。要水平打印,请在菜单项之前打印一个逗号,除非它是第一项。即 - if (i != 0) cout &lt;&lt; ", ";
  • 不,这不会是“Rock, Paper Scissors”的原因,因为它已经使用了逗号,但它的行为就像一个endl,他们无论如何也要压缩这个“巨大的”代码? @enhzflep
  • 那么,我认为您希望输出为Rock Paper Scissors,而不是Rock, Paper, Scissors
  • 是的!这正是我想要的。 @enhzflep

标签: c++ visual-studio-2010 visual-studio visual-studio-2012 menu


【解决方案1】:

有很多不同的方法可以解决这个问题。我更愿意在我自己的代码中以不同的方式来处理它,但我试图在一天中的这个时间写出尽可能接近你自己的代码的东西。

您可以对任何需要显示的菜单重复使用相同的函数 - 只需为字符串列表和该数组中字符串的计数赋予不同的值。更好的是 - 使用 std::vector&lt;string&gt;

我没有在主函数中硬编码菜单项的数量,而是通过获取字符串数组的总大小并将其除以第一个元素的大小来计算。由于无论字符串的长度如何,每个元素都为 sizeof 提供相同的值,因此您可以计算数组中的元素数。但请注意 - 这个技巧在 getUserChoice 函数内部不起作用 - 到那时,数组已经降级为指针,并且函数无法告诉数组中有多少项,不像 main - 那是为什么我计算那里的数字。使用字符串向量会更简洁,因为您可以将向量的引用传递给函数,然后在函数内部调用向量的.size() 方法来获取它包含的项目数。可能比你刚才所做的有点早,因此代码的风格与你自己的相似。

希望对您有所帮助。 :)

#include <iostream>
#include <string>
#include <windows.h>

using namespace std;

int getUserChoice(string *items, int numItems)
{
    int curSel = 0, textAttrib;
    bool selectionMade = false, needsUpdate = true; // we want to clearscreen first time through
    while (!selectionMade)
    {
        // only redraw the screen if something has changed, or we're on the first iteration of
        // our while loop.
        if (needsUpdate)
        {
            system("cls");
            needsUpdate = false;

            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
            cout << "Main Menu" << endl;
            cout << "(navigate with arrow keys, select with enter)" << endl << endl;
            for (int i=0; i<numItems; i++)
            {
                if (i == curSel)
                    textAttrib = 11;
                else
                    textAttrib = 15;

                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), textAttrib);

                if (i)
                    cout << " ";

                cout << items[i];
            }
        }

        if (GetAsyncKeyState(VK_LEFT) != 0)
        {
             curSel--;
             needsUpdate = true;
        }

        else if (GetAsyncKeyState(VK_RIGHT) != 0)
        {
             curSel++;
             needsUpdate = true;
        }

        else if (GetAsyncKeyState(VK_RETURN) != 0)
            selectionMade = true;

        if (curSel < 0)
            curSel = numItems-1;
        else if (curSel > (numItems-1) )
            curSel = 0;
        Sleep(100);
    }
    char dummy[10];
    cin.getline(dummy, 10);   // clear the enter key from the kbd buffer
    return curSel;
}


int main()
{
    string Menu[] = {"Rock", "Paper", "Scissors"};

    int selection;
    selection = getUserChoice(Menu, sizeof(Menu)/sizeof(Menu[0]) );

    cout << "You chose: " << Menu[selection] << endl;
}

【讨论】:

  • 哇!这非常适合我的需要!特别是因为它在一个 void function
  • 太棒了!不客气。 (它实际上不是一个 void 函数,因为它的价值 - 它返回一个值 - 所以它被取消资格)你是否收到我发布的代码的错误,还是在进行更改后出现错误? (我先测试了 sn-p 并且想不出任何无效的空指针错误会发生在哪里)您应该使用调试器逐步检查它以找到错误。老实说,真的看不出它怎么能变得更短。
  • 是的,我什至根本没有更改代码就得到了错误!我不知道为什么,你认为我应该怎么做?
  • 这是我得到的错误!我把它放到上传的图片中。 tinypic.com/view.php?pic=2zegq2r&s=8#.VDnPH6UznwI
  • 忘记添加标签了.. @enhzflep
猜你喜欢
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 2013-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多