字符数组的奇数输出

问题描述:

我目前正在编写一个命令行“解析器”,可以这么说,到目前为止它一直在工作,直到我尝试了一些方法来添加选项/参数。字符数组的奇数输出

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ÌÌÌÌÌÌÌÌÌÌÌÌÌÌØNi

我也不太清楚关于C++字符数组,但我不知道我怎么得到这个输出。任何帮助都将不胜感激。有关代码的任何问题,或者如果您需要更多的代码,只需评论,预先感谢

cout << the_command << endl; 

在开始将com中的字符复制到the_command之前,该数组完全未初始化。我会代表这些未知字符问号(当然,他们很可能没有真正问号):

? ? ? ? ? 

这意味着你不知道的char S的数组中的值是什么。然后,您只将字符从the_command复制gocom,所以你的数组现在包含:

g o ? ? ? 

所以,当你试图输出这个数组,输出流不知道什么时候停止。您需要确保在o之后插入\0。这样做将是一个办法:

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); 
    } 
} 
+0

我想让命令和使用if语句或switch语句来确定要运行哪个函数 – PurityLake 2013-03-21 20:22:50

+0

@PurityLake什么阻止你?看我的编辑。 – 2013-03-21 20:24:57

+0

好吧,你有一个点,我会遇到与字符数组的麻烦,只是不知道如何使用字符串分离命令,是不是字符串流为我做? – PurityLake 2013-03-21 20:27:13

这是因为您的代码中有缓冲区溢出。您将不确定长度的字符串复制到char [5]缓冲区中......基本上,您的循环正在将由输入字符串确定的多个字节复制到char [5]数组的末尾,该数组不再以null结尾,所以“cout”只是读取,直到它找到空字节。

+0

我看它的方式是,第一个命令是不大于5个字符 – PurityLake 2013-03-21 20:16:56

+1

好了,从理论上说,'如果(COM [I] =='“) break;'应该防止输入buf溢出''go north'''。 (当然,代码本身并不安全,因为您无法保证所有输入的条件都可以得到。) – us2012 2013-03-21 20:17:02

+2

好的catch,无论哪种方式,缓冲区都不是空终止的,导致cout读得太远。 – Ryan 2013-03-21 20:18:39

在读取最后一个字符后,您不是null-terminating the_command。或者做任何边界检查。

请使用std::string代替。

更改代码:

if (com[i] == ' ') 
{ 
    com[i] = '\0'; 
    break; 
} 

这将确保有你的字符数组的最后一个空终止。你看到垃圾的原因是因为std::cout将愉快地打印字符,直到它看到一个空终止符。

基本上the_command[5]包含垃圾,因为没有被初始化并且不包含字符终止符。你可以先清除它,当您打印char阵列这样,字符继续插入,直到空字符\0在字符串中发现你会被罚款

for (i = 0; i < 5; i++) { 
    the_command[i] = 0; 
}