我正在用c++编写一个小型解释器,但它返回给我一个错误“向量下标超出范围”

问题描述 投票:0回答:1

我正在用这两个命令编写一个非常简单的解释器:“print:value”,用于打印和“printnl:value”,用于在新行中打印,我使用向量来存储命令和值。 问题是,当我输入某些内容时,它会返回错误“向量下标超出范围”和一些随机退出代码。 这是代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

vector<string> brk_token(string text, char breakon) {
    vector<string> tokens;
    string token = "";
    for (int i = 0;i < text.size(); i++) {
        if (text.at(i) != breakon) {
            token += text.at(i);
        }
        else {
            tokens.push_back(token);
            token = "";
        }


    }
    return tokens;
}

int main() {

    string program;
    while (true) {
        getline(cin, program);
        if (brk_token(program.c_str(), ':')[0] == "print") {
            cout << brk_token(program.c_str(), ':')[1];
        }
        else if (brk_token(program.c_str(), ':')[0] == "printnl") {
            cout << brk_token(program.c_str(), ':')[1] << "\n";
        }
        if (program == "break") {
            break;
        }
    }

    return 0;
}

我写了:“print:hello”和“printnl:hello”,每次返回该错误时,我写了一些随机字符,结果是相同的,有人可以帮忙吗?

c++ vector interpreter
1个回答
2
投票

brk_token()
内部,当循环到达字符串末尾时,您不会将最后一个
token
推入
vector
。因此,在
main()
内部,当您尝试访问不存在的 vector[1] 元素时,您会遇到
未定义的行为。 

此外,您的代码还存在一些其他问题:

  • string::at()

     方法在运行时执行边界检查,但您在迭代 
    for
    string
     循环中执行自己的边界检查,因此使用 
    at()
     是无用的开销。您可以安全地使用 
    string::operator[]
     代替。

  • while

    中的
    main()
    循环不会在处理
    getline()
    之前检查
    string
    是否成功。循环的结构应该像这样:

    while (getline(cin, program)) { ... }
    
    
  • 调用

    brk_token()

     时,您将 
    string
     转换为 
    const char*
    ,只是为了再次将其转换回 
    string
    。您根本不需要在此代码中使用 
    string::c_str()

    反复调用
  • brk_token()

    太过分了。每个 
    string
     调用一次并将结果保存到本地变量中,然后您可以在使用之前进行验证。

说了这么多,试试这个:

#include <iostream> #include <string> #include <vector> using namespace std; vector<string> brk_token(const string &text, char breakon) { vector<string> tokens; string token; for (size_t i = 0; i < text.size(); ++i) { if (text[i] != breakon) { token += text[i]; } else { tokens.push_back(token); token = ""; } } if (!token.empty()) tokens.push_back(token); return tokens; } int main() { string program; vector<string> tokens; while (getline(cin, program) && (program != "break")) { tokens = brk_token(program, ':'); if (tokens.size() != 2) { cout << "Bad input\n"; } else if (tokens[0] == "print") { cout << tokens[1]; } else if (tokens[0] == "printnl") { cout << tokens[1] << '\n'; } else { cout << "Unknown input\n"; } } return 0; }
    
© www.soinside.com 2019 - 2024. All rights reserved.