为什么printf只显示第一个字母?

4
首先,我有一个函数,其中我将标志存储在unsigned char*类型中。例如对于Abcdef!?,它是[65 0] [98 0] [99 0] [100 0] [101 0] [102 0] [33 0] [63 0],每个符号在Unicode中占用2个字节。

当我使用for(unsigned char i=0; i<17; i++) printf("%c", pointer[i]);时,一切正常,它显示Abcdef!?。但是当我使用printf("%s" pointer);时,它只给我A,什么都没有。你能告诉我为什么吗?


6
第二个值为0,它是一个“unsigned char*”数组类型:printf停止工作。你能展示一个 [mcve] 吗? - Jean-François Fabre
6
看到所有那些0字节了吗? %s是用来打印C字符串的,它以空字符为结尾;这被称为空字符结束字符串(Null Terminated Byte String)。因此,在第一个0字节之前,只能获取到第一个字符,然后就停止读取任何其他字符。 - BoBTFish
3
当你说“Unicode系统”时,你是指UTF-16或类似的编码方式,对吧?Unicode本身并不是一种编码方式,它只是将字符映射为数字的一种规范。 - Konrad Rudolph
尽管人们可能认为 printf 不是 C++ 风格的,但它与 iostreams 一样是 C++ 标准的一部分。我无法看出在 C 和 C++ 中将 Unicode 存储在 unsigned char * 中的可取性方面有任何区别。 - Martin Bonner supports Monica
1
@MartinBonner 即使在这种特殊情况下,C和C++的答案恰好相同,但通常情况下远非如此显然。在Stack Overflow上有足够多的问题被标记为[tag:c]和[tag:c++],它们的答案是不同的。将问题限制和聚焦于一种语言是有意义的。 - Konrad Rudolph
显示剩余5条评论
1个回答

7
因为printf("%s", pointer)字面意思是:从存储在pointer中的字符开始打印,直到遇到'\0'

'A'后面紧跟着一个'\0',因此只打印了第一个字符。


3
也许可以。这在Windows上可行(其中wchar_t存储UTF-16)。但这不适用于Linux平台,它们倾向于使用四字节的wchar_t来存储UCS4(而这不是UCS4)。 - Martin Bonner supports Monica
5
@FiddlingBits:不可以。%ls需要一个指向wchar_t类型的指针,而不是char类型的指针。即使wchar_t是16位小端格式(这是MSVC错误的定义,与Unicode不兼容),将char数组视为wchar_t类型违反了别名规则,可能也无法遵守对齐要求。 - R.. GitHub STOP HELPING ICE
1
@FiddlingBits:我想这应该是正式的UB,因为%ls是用于wchar_t*的。但是,C++标签已从问题中删除,而且我对C中的这些事情不是100%确定。 - Christian Hackl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接