我正在用这两个命令编写一个非常简单的解释器:“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”,每次返回该错误时,我写了一些随机字符,结果是相同的,有人可以帮忙吗?
在
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;
}