2013-02-14 37 views
1

我的代码是:突然额外的索引值

char randomChar(int randMax) { 
    return (65 + rand() % randMax); 
} 

int main() { 

    srand(time(NULL)); 
    const int SIZE = 4; 
    const int LETTERS = 6; 
    char code[SIZE]; 

    for (int i = 0; i < SIZE; i++) { 
     code[i] = randomChar(LETTERS); 
    } 

    cout << code; 

    return 0; 
} 

的问题是,即使我已经设定的代码阵列是长度为4时,randomChar函数返回4个字母+一些额外的随机标志。

+2

摆脱那些丑陋的字符数组,并使用'std :: string'。你不会再有这种问题了。使用C++的美妙之处,将指针和普通数组包装到安全的操场中。 – stefan 2013-02-14 13:00:32

+0

我们还没有在我的课上学到指针:/ – user1784297 2013-02-14 13:19:11

+0

更好。在学习C++的开始阶段,你不需要它。你不需要知道任何关于使用std :: string的指针。 – stefan 2013-02-14 13:21:17

回答

2

您应该在数组中放置一个终止零字符。否则,您可能会在阵列结束后打印垃圾。始终与声明大小为1比你更需要的数组,然后设置为0。

最后一个元素试试这个代码:

char randomChar(int randMax) { 
    return (65 + rand() % randMax); 
} 

int main() { 

    srand(time(NULL)); 
    const int SIZE = 4; 
    const int LETTERS = 6; 
    char code[SIZE + 1]; 

    for (int i = 0; i < SIZE; i++) { 
     code[i] = randomChar(LETTERS); 
    } 

    code[SIZE] = 0; // or '\0' 
    cout << code; 

    return 0; 
} 
+0

像'char code [SIZE + 1] = {0};' – borisbn 2013-02-14 13:02:30

+4

'这样的'代码'初始化会更好,在这种情况下是的,但我试图给出一个一般的解释。用零初始化并不总是足够的(例如,如果在一个循环中重新使用char数组)。零终止字符串是应该始终完成的事情。 – 2013-02-14 13:10:27

+0

嗯......的确如此。没想过 – borisbn 2013-02-14 13:12:19

0

您的字符串不是零终止。

你可能不得不这样做:

char randomChar(int randMax) { 
    return (65 + rand() % randMax); 
} 

int main() { 

srand(time(NULL)); 
const int SIZE = 4; 
const int LETTERS = 6; 
char code[SIZE + 1]; 

for (int i = 0; i < SIZE; i++) { 
    code[i] = randomChar(LETTERS); 
} 

code[SIZE] = '\0'; 
cout << code; 


return 0; 
} 

,或者所建议的评议@borisbn:

char randomChar(int randMax) { 
    return (65 + rand() % randMax); 
} 

int main() { 

srand(time(NULL)); 
const int SIZE = 4; 
const int LETTERS = 6; 
char code[SIZE + 1] = {0}; 

for (int i = 0; i < SIZE; i++) { 
    code[i] = randomChar(LETTERS); 
} 

cout << code; 


return 0; 
} 

但是,如果有任何宇宙赫然出现在其中( '\ 0'= 0)是真的,后者会在那里失败。

+0

不是'SIZE + 1',只是大小(当加0时) – 2013-02-14 13:00:29

+0

@Ivaylo:so true – 2013-02-14 13:01:20

+0

像'char代码[SIZE + 1] = {0}一样初始化'code'会更好; – borisbn 2013-02-14 13:02:08

0

正如其他人指出的,你不是null终止你的char数组。如果您使用适当的C++方式,即使用std::string这基本上是char数组的包装类,则可以忘记这类问题。以下是如何实现在C++相同的逻辑:

#include <cstdlib> 
#include <ctime> 
#include <iostream> 
#include <string> 

char randomChar(const int randMax) // suggestion, not a necessity: mark randMax as const since you never intend to modify it here. 
{ 
    return (65 + std::rand() % randMax); 
} 

int main() 
{ 
    std::srand(std::time(NULL)); 
    const int SIZE = 4; 
    const int LETTERS = 6; 
    std::string code; 
    for (int i = 0; i < SIZE; i++) 
    { 
     code.insert(code.end(), randomChar(LETTERS)); 
    } 
    std::cout << code << std::endl; 
    return 0; 
} 
0

在C中,字符串是零封端的,这是因为一个字符串的长度不与它因此是确定在何处字符串的一些方法需要相关联的结束。 C和C++通过在字符串的末尾放置一个零字符来实现这一点。当你做类似char* text = "simples";的东西时,编译器会为你做这件事,但是当你产生你自己的字符串时,你需要为你感兴趣的字符留下多一个字符的空间,并将这个字符设置为\0

你在最后得到虚假字符的原因是cout正在尽力打印出从你的数组开始的字符,直到碰巧碰到一个零字节,它将被解释为字符串的结尾。

因此要使用此替换您main()功能:

int main() { 

    srand(time(NULL)); 
    const int SIZE = 4; 
    const int LETTERS = 6; 
    char code[SIZE + 1]; 

    for (int i = 0; i < SIZE; i++) { 
     code[i] = randomChar(LETTERS); 
    } 

    // Need to zero-terminate the string 
    code[SIZE] = '\0'; 
    cout << code; 

    return 0; 
} 

(你也可以做code[SIZE] = 0但我更喜欢的\0的表现 - 无论是会产生效果完全一样)

零终止也是C和C++中字符串处理速度比它慢的主要原因之一:几乎每个字符串操作都需要从头到尾扫描字符串以找到空终止符。