我用c ++编写游戏,我想让它按字符输出字符串,并使用Sleep()函数减慢输出。字符串是:
string output = "It is Super Effective!" + '\n';
当我尝试cout << output
时,它会返回"r Effective"
而没有新行
显示功能的代码是
void textDisplay(string s){
s = " " + s;
for (int i = 0; i < s.size(); i++){
char c = s[i];
cout << c;
Sleep(20);
}
}
答案 0 :(得分:9)
这是因为"It is Super Effective!" + '\n'
被解释为指向C字符串的指针加上字符\n
的整数值,即ASCII中的10。这是在分配给C ++ - 字符串之前发生的。
您会看到,如果您从C字符串的开头计算了10个字符,那么确实会以r
结束。
所以,这里发生了什么,详细和顺序:
"It is Super Effective!"
被解释为指向初始I
字符(C字符串)的字符指针。\n
的整数值)来得到指向r
(仍为C字符串)的指针。"r Effective!"
来构造C ++ - 字符串。以图形形式:
base + 0: | I | -------+
base + 1: | t | |
base + 2: | | |
base + 3: | i | |
base + 4: | s | |
base + 5: | | Add ten
base + 6: | S | |
base + 7: | u | |
base + 8: | p | |
base + 9: | e | |
base + 10: | r | <------+
base + 11: | |
base + 12: | E |
:
base + 21: | ! |
base + 22: | \0 |
您可以更改它以将字符添加到C ++字符串而不是C字符串:
string output = "It is Super Effective!";
output += '\n';
但我不完全确定你为什么不这样做:
string output = "It is Super Effective!\n";
您可能需要注意的另一件事。将字符刷新到标准输出的可能性只会在发送换行符时发生,这意味着您似乎在一次点击中获得整个字符串,大约七分钟在您预期出现第一个字符后,左右。
如果发生这种情况,请记住在每个字符后刷新流:
cout << c << flush;
答案 1 :(得分:3)
在此上下文中,+
未将字符连接到字符串文字,而是返回指针值偏移\n
字节。在ASCII中,这将是0x0A
或10.这是因为字符串文字是const char
的数组,然后衰减到其第一个元素的地址。 +
运算符会将10个字符偏移到该元素之后。
1
0 1 2 3 4 5 6 7 8 9 0
|I|t| |i|s| |S|u|p|e|r| |E|f|f|e|c|t|i|v|e|!|
您可以先修改string
,然后附加。
string output = "It is Super Effective!";
output += '\n';
或者,您可以使用字符串文字串联,删除+
并使用"\n"
代替:
string output = "It is Super Effective!" "\n";
或者只是将整个事情变成一个字符串,这将是最清楚的。
string output = "It is Super Effective!\n";
答案 2 :(得分:3)
当C ++编译器遇到程序中的运算符时,它会执行重载解析,就像重载函数一样。二进制operator+
有很多重载,但你关心这两个:
std::string operator+(std::string, char) // string concatenation
const char* operator+(const char*, std::ptrdiff_t) // pointer arithmetic
其他答案已经解释了+
的这两个替代含义,我将向您展示编译器如何确定第二个含义更好。
您的实际参数类型为const char[N]
和char
。第一个参数可以使用数组到指针衰减隐式转换为const char*
,使用数组到指针衰减后跟“用户定义的转换”(std::string
隐式转换为std::string
隐式构造函数)。第二个参数可以通过隐式扩展转换为任何其他整数类型,包括std::ptrdiff_t
。
所有不同类型的转换都根据C ++标准中的表进行排名,在此表中,用户定义的转换仅用作最后的手段。因此指针算术解释获胜。