我正在编写一个命令行“解析器”,可以这么说,到目前为止,它一直在工作,直到我尝试了几种方法来添加选项/参数。
void parser::nextCom() {
cout << parser::prompt; // parser::prompt = "> "
string com;
getline(cin, com);
char the_command[5]; // i want this to store the command e.g. "go" given that go is a command
for (int i = 0; i < com.size(); i++) {
if (com[i] == ' ') break;
else the_command[i] = com[i];
}
cout << the_command << endl;
}
复制命令但在打印机the_command
到控制台时会显示一些非常不需要的字符。
如果我将“go north”作为命令传递,这就是我得到的:
goÌÌÌÌÌÌÌÌÌÌÌÌÌÌØNi
我对C ++中的char数组不太确定,但我不知道如何得到这个输出。任何帮助都将不胜感激。有关代码的任何问题,或者如果您需要更多我的代码,请发表评论,提前致谢
答案 0 :(得分:4)
cout << the_command << endl;
当您打印这样的char
数组时,将继续插入字符,直到在字符串中找到空字符\0
。
在开始将字符从com
复制到the_command
之前,阵列完全未初始化。我会用问号代表这些未知字符(但当然,它们可能实际上不是问号):
? ? ? ? ?
这意味着您不知道数组中char
s的值是什么。然后,您只将g
和o
中的字符从the_command
复制到com
,因此您的数组现在包含:
g o ? ? ?
因此,当您尝试输出此数组时,输出流不知道何时停止。您需要确保在\0
之后插入o
。一种方法是:
for (int i = 0; i < com.size(); i++) {
if (com[i] == ' ') {
the_command[i] = '\0';
break;
}
else the_command[i] = com[i];
}
这将使数组如下:
g o \0 ? ?
但是,只要坚持std::string
,你就会好得多。我不想想你可以避免使用这个阵列的麻烦。以下是我编写函数的方法:
void parser::nextCom() {
std::cout << parser::prompt;
std::string command_line, command;
std::getline(cin, command_line);
std::stringstream command_line_stream(command_line);
command_line_stream >> command;
if (command == "go") {
std::string direction;
command_line_stream >> direction;
go(direction);
}
}
答案 1 :(得分:3)
在读取最后一个字符后,您不会终止the_command
。或者执行任何边界检查。
请改为使用std::string
。
答案 2 :(得分:3)
将代码更改为:
if (com[i] == ' ')
{
com[i] = '\0';
break;
}
这将确保char数组末尾有一个null终止符。你看到垃圾的原因是因为std::cout
会很高兴地打印字符,直到看到空终止符。
答案 3 :(得分:1)
这是因为您的代码中存在缓冲区溢出。你将一个不确定长度的字符串复制到一个char [5]缓冲区...基本上,你的循环正在复制输入字符串确定的字节数,超过char [5]数组的末尾,不再是null终止,所以“cout”只是读取,直到找到空字节。
答案 4 :(得分:1)
基本上the_command[5]
包含垃圾,因为未初始化且不包含字符终止符。你可以先清除它,你会没事的
for (i = 0; i < 5; i++) {
the_command[i] = 0;
}