for循环异常c ++

时间:2018-08-03 00:45:30

标签: c++ for-loop runtime-error

对于我的C ++类,我必须编写一个程序,该程序使用一个包含用户字母的电话号码(例如1-800-GOFEDEX),并返回包含他们应拨打的实际号码的电话号码。我在for循环中有转换逻辑:

    for (int i = 0; i <= 7; i++) {
    switch (letters[i]){
        case 'A':
        case 'B':
        case 'C':
            decodedNumber[i] = '2';
            continue;
        case 'D':
        case 'E':
        case 'F':
            decodedNumber[i] = '3';
            continue;
        case 'G':
        case 'H':
        case 'I':
            decodedNumber[i] = '4';
            continue;
        case 'J':
        case 'K':
        case 'L':
            decodedNumber[i] = '5';
            continue;
        case 'M':
        case 'N':
        case 'O':
            decodedNumber[i] = '6';
            continue;
        case 'P':
        case 'Q':
        case 'R':
        case 'S':
            decodedNumber[i] = '7';
            continue;
        case 'T':
        case 'U':
        case 'V':
            decodedNumber[i] = '8';
            continue;
        case 'W':
        case 'X':
        case 'Y':
        case 'Z':
            decodedNumber[i] = '9';
            continue;
        //the default will simply copy it over (in case there is a number mixed with the letters)
        default:
            decodedNumber[i] = i;
            continue;
    }
} //End of for loop

它可以正常编译,但是当我运行它时,它将循环一次,然后出现此错误:

runtime error

我知道它至少会循环一次,因为您可以在此图片的decodedNumber变量的第一位置看到数字4:

Visual Studio During Debugging

在switch语句的所有情况下,我都尝试将i更改为i+1,但这也不起作用。

我们非常感谢您的帮助!

Here's the entire program code(如果需要)

3 个答案:

答案 0 :(得分:1)

(一般建议)

如果您将查找机制设置为类似,我们可以说(拨号盘说明):

include <map>

// Dial-pad description:
const std::map<char, unsigned int> lut{
    {'1',1},
    {'2',2}, {'A',2}, {'B',2}, {'C',2},
    {'3',3}, {'D',3}, {'E',3}, {'F',3},
    {'4',4}, {'G',4}, {'H',4}, {'I',4},
    {'5',5}, {'J',5}, {'K',5}, {'L',5},
    {'6',6}, {'M',6}, {'N',6}, {'O',6},
    {'7',7}, {'P',7}, {'Q',7}, {'R',7}, {'S',7},
    {'8',8}, {'T',8}, {'U',8}, {'V',8},
    {'9',9}, {'W',9}, {'X',9}, {'Y',9}, {'Z',9},
    {'0',0}
};

然后,代码变得简单:(并具有抽象级别)

#include <string>
#include <vector>

std::string Dial{"1-800-GOFEDEX"};
std::vector<unsigned int> Number;

for (auto & Ch : Dial) {
    auto it = lut.find(Ch);
    if (it != lut.end())
        Number.push_back(it->second);
}
  • 在这种情况下,您也可以添加对其他语言或其他拨号盘变体等的支持,而无需修改代码(地图初始化除外)。双语(0600-06FF第二语言的值范围)拨号盘,例如:

enter image description here

-

地图lut的替代方法(如果“地图效率”是一个问题):

#include <array>
#include <climits>

std::array<unsigned int, 100> lut; // ASCII Code: '-' 45, '0'-'9': 48-57, 'A'-'Z': 65-90 
lut.fill(UINT_MAX);

// Dial-pad description:
lut['1'] = 1;
lut['2'] = lut['A'] = lut['B'] = lut['C'] = 2;
lut['3'] = lut['D'] = lut['E'] = lut['F'] = 3;
lut['4'] = lut['G'] = lut['H'] = lut['I'] = 4;
lut['5'] = lut['J'] = lut['K'] = lut['L'] = 5;
lut['6'] = lut['M'] = lut['N'] = lut['O'] = 6;
lut['7'] = lut['P'] = lut['Q'] = lut['R'] = lut['S'] = 7;
lut['8'] = lut['T'] = lut['U'] = lut['V'] = 8;
lut['9'] = lut['W'] = lut['X'] = lut['Y'] = lut['Z'] = 9;
lut['0'] = 0;

在这种情况下,代码如下:

#include <string>
#include <vector>

std::string Dial{"1-800-GOFEDEX"};
std::vector<unsigned int> Number;

for (auto & Ch : Dial)
    if (lut[Ch] < 10)
        Number.push_back(lut[Ch]);

答案 1 :(得分:0)

  1. 正如评论所说,如果for (int i = 0; i <= 7; i++)在调用letters[i]时保留字符串"GOFEDEX",则letters[i]可能是错误的。尽管letters[7]保留'\ 0'字符并非总是如此,但循环到i == 7并不是很好。

  2. 如果
  3. decodedNumber[i]的长度小于或等于i,也可能引发数组索引异常。我想这是因为decodedNumber[i] = '6';时在行i == 1中引发了异常。字符串decodedNumber没有足够的空间来保留新字符,因为operator[]不会为字符串分配内存。

  4. decodedNumber[i] = i;可能应该是decodedNumber[i] = letters[i];

答案 2 :(得分:0)

tl; dr:

更改第25行

string decodedNumber, returnedNumber.

ADD第26行

decodedNumber.resize(letters.size());

好,几件事。

  1. 不要use namespace std。习惯于写出std::。这样,当您有多个名称空间时,您不会在名称相同的函数之间感到困惑。

  2. 第22行,功能应该起作用。

  3. 您正在传递要切换的字符串,然后尝试像字符数组一样访问它。如果您正在玩弦乐,请使用letters.at(i).at(i)是安全的,当您离开字符串的末尾时,它将引发异常。

  4. 问题在于您的字符串decodedNumber = ""是引发下标错误的原因。创建该对象时,它的大小为零,如所想象的,没有bueno。调整字符串大小decodedNumber.resize(letters.size())应该可以解决此问题。

  5. 在每种情况下都不需要continue

  6. 请注意您的父母。请保持格式一致。

  7. 我会亲自替换

    while(running) {...}
    

    使用

    do {...}
    while(running);
    

do while确保至少运行一次,而while至少运行一次。