类成员函数at()和带有循环的switch语句

Class member function at() and switch statements with a loop

本文关键字:循环 switch 语句 函数 成员 at      更新时间:2023-10-16

这是我第一次在这里发帖,所以如果我做错了什么,提前道歉。我正在研究一个项目,其中一部分程序需要将电话单词(IE"Rad-Code")翻译成相应的电话号码(IE 723-2633)。我试图使用开关语句以及at()和length()类成员函数。我试着切换这一节的代码顺序,但它一直给我一个错误声明:"输入电话单词:Rad-Code 723-2633terminate抛出'std::out_of_range'的实例后调用what(): basic_string::at: __n(这是8)>= this->size()(这是8)"

下面是有问题的代码:

else if (choice == PHONE_WORD)
{
        cout << "nEnter the phone word: ";
        cin >> phoneWord;
        /*while (phoneWord.length() != 8)
        {
            cout << "Please enter a valid phone number length: ";
            getline(cin, phoneWord);
        }*/
        for (int i = 0; i < phoneWord.length(); i++)
        switch (phoneWord.at(i))
        {
            case 'A':
            case 'a':
            case 'B':
            case 'b':
            case 'C':
            case 'c':
                cout << "2";
                break;
            case 'D':
            case 'd':
            case 'E':
            case 'e':
            case 'F':
            case 'f':
                cout << "3";
                break;
            case 'G':
            case 'g':
            case 'H':
            case 'h':
            case 'I':
            case 'i':
                cout << "4";
                break;
            case 'J':
            case 'j':
            case 'K':
            case 'k':
            case 'L':
            case 'l':
                cout << "5";
                break;
            case 'M':
            case 'm':
            case 'N':
            case 'n':
            case 'O':
            case 'o':
                cout << "6";
                break;
            case 'P':
            case 'p':
            case 'Q':
            case 'q':
            case 'R':
            case 'r':
            case 'S':
            case 's':
                cout << "7";
                break;
            case 'T':
            case 't':
            case 'U':
            case 'u':
            case 'V':
            case 'v':
                cout << "8";
                break;
            case 'W':
            case 'w':
            case 'X':
            case 'x':
            case 'Y':
            case 'y':
            case 'Z':
            case 'z':
                cout << "9";
                break;
            case '-':
                cout << "-";
                break;
            default:
                cout << "Please enter a valid input: ";
                break;
        }
        cout << phoneWord << " translates to " << phoneWord.at(0) << phoneWord.at(1) << phoneWord.at(2) << phoneWord.at(3) << phoneWord.at(4) << phoneWord.at(5) << phoneWord.at(6) << phoneWord.at(8) << ".";
}

这是你的问题:phoneWord.at(8)。应该是' phoneWord.at(7).

这里有一个更简洁的方式来实现你的意图:

// DIGIT_MAP is a static map of characters to digits, 'a' -> 0, 'q' -> 7 etc.
for (auto it = phoneWord.cbegin(); it != phoneWord.cend(); ++it)
   cout << DIGIT_MAP[tolower(*it)];

不需要使用at,这就是迭代器的作用

您会注意到,如果索引超出范围,std::vector::at会抛出异常:

如果n越界,则抛出out_of_range

正如@Retired Ninja在评论中指出的:你最终的cout语句在访问元素

之前没有检查索引
cout << phoneWord << " translates to " << phoneWord.at(0) << phoneWord.at(1) << phoneWord.at(2) << phoneWord.at(3) << phoneWord.at(4) << phoneWord.at(5) << phoneWord.at(6) << phoneWord.at(8) << ".";

很可能最终的phoneWord.at(8)是指phoneWord.at(7),但你可以简化它来防止这些问题,像这样:

std::cout << phoneWord << " translates to ";
for (auto c : phoneWord)
    std::cout << c;
std::cout << "." << std::endl;

这将安全地遍历phoneWord中的所有值,您无需担心访问超出范围的元素。如果phoneWord

中有4,8或20个字符,则可以安全工作