对于以下代码,在我的PC上,char \0
将始终产生空格(使用cout
打印时)。但是,在我朋友的PC上,char \0
的结果将始终生成char a
。代码和截图如下:
#include <iostream>
using namespace std;
// Function main
int main()
{
cout << "xxx" << '\0' << "yyy" << endl;
return 0;
}
左:在我的电脑上。 正确:在我朋友的电脑上。
这里发生了什么?为什么不同的PC上的结果不同?
PS :
即使我们共享相同的可执行exe
文件(即在我的电脑上编译并在两台电脑上运行),结果仍然会有所不同。
我们都使用visual studio 2010和相同的项目字符集。
这里可能有一些缓冲区溢出,但请注意我始终获得space
这一事实,而我的朋友总是得到一个字符a
。
如果我们都 cout<<ends
,它会分享相同的功能。
答案 0 :(得分:6)
字符\0
或ASCII 0
不是可打印的字符,没有标准的输出方式。
可打印的ASCII范围从0x20
到0x7E
,请参阅Wikipedia:ASCII
答案 1 :(得分:2)
对于“不可打印的字符”(对于ASCII是0x20-0x7e [*]范围之外的任何字符),输出在技术上是未定义的,实际的视觉输出将取决于几个方面:
实际输出设备 - 如果您在Windows命令行提示符下查看该字符,它可能与Linux下的终端窗口看起来不同,并且使用真正的(30岁以上)VT100终端,它将最有可能再次看起来不同。 (事实上,当我第一次用于为使用串行输入的终端编写代码时,我们习惯用“NUL”字符“填充”某些控制序列,因为当转义序列“复杂”时终端会丢弃一些字符 - 比如清楚 - 屏幕,它可能不会收到接下来的5-6个字符,所以我们要添加额外的10个NUL字符,这样我们就会丢失NUL而不是我们想要在屏幕上打印的有意义文本的一部分)。
如果适用,选择用于显示文本的字体也可能很重要(在这种特殊情况下似乎就是这种情况,但不要依赖它)。当然,这也适用于可打印字符,但除了一些“特殊”字体(Zapf Dingbats,符号是明显的例子)之外,“可打印范围”确实符合我们的预期。 “不可打印”的范围没有那么明确。
实际打印的方法 - 例如使用cout
或printf
将产生与“将字符戳入PC上的帧缓冲存储器[文本模式]”不同的结果。
要获得打印不可打印字符的一致结果,您需要将它们处理为定义为可打印的内容。
[*]许多系统支持扩展范围,例如原始IBM / PC的范围为0x20-0xff,现代系统使用多个字节来表示“不可打印”的字符,例如UTF-8编码,常用字符[在欧洲语言中]用单个字节编码,而较不常见的字符用两个,三个或四个字节编码。即使在这里,实际输出取决于所选的确切字体。
答案 2 :(得分:1)
如上所述,它是实现定义的。在我的终端上,我得到^@
。 NULL
终结符用于打印字符串,但在这种情况下,您尝试输出字符本身(并且它将具有不同的表示形式,从随机字符到任何内容。)
答案 3 :(得分:0)
'\0'
是一个终止字符,用于知道字符串的结束位置,例如,这将打印ab
:
#include <iostream>
int main(int argc, char* argv[])
{
char str[]= { 'a', 'b', '\0' };
std::cout <<str<< std::endl;
return 0;
}
如果您只打印最后一个字符,它不应该打印任何内容,但不会立即终止而不打印任何内容。
您所谈论的空间可能是由std::endl
这里没有未定义的行为,未定义的行为通常是在相反的情况下引起的,其中有没有终止字符('\0'
)然后你打印出你的内存已分配的块和您打印的内容未定义。
修改强>
这真的很奇怪,你说的没有意义,请发布所有你的代码
答案 4 :(得分:0)
#include < iostream >
using namespace std;
int main()
{
cout << "xxx" << '\0' << "yyy" << endl;
return 0;
}
我不知道为什么你会得到不同的o / p。 用g ++检查一次。我用g ++获得了这个o / p