C 如何打印具有或不具有多字符的长度相同的字符串?
我正在做K&R书中的练习1-22。它要求在字符串中预定义的字符数之后折叠长行(即进入新行) 当我测试这个程序时,它运行得很好,但是我看到一些行比它们应该的更早“折叠”。我注意到出现特殊字符的是线条,例如: öşçğC 如何打印具有或不具有多字符的长度相同的字符串?,c,character-encoding,C,Character Encoding,我正在做K&R书中的练习1-22。它要求在字符串中预定义的字符数之后折叠长行(即进入新行) 当我测试这个程序时,它运行得很好,但是我看到一些行比它们应该的更早“折叠”。我注意到出现特殊字符的是线条,例如: öşçğ 因此,我的问题是,如何确保打印行的最大长度相同,有或没有多字符?代码中会发生什么? K&R是在所有字符都编码在一个字符上的时代编写的。此类编码标准的示例为或 如今,领先的编码标准是UNICODE,它有多种风格。使用可变长度方案,编码用于表示8位字节上的数千个unicode字符: a
因此,我的问题是,如何确保打印行的最大长度相同,有或没有多字符?代码中会发生什么? K&R是在所有字符都编码在一个字符上的时代编写的。此类编码标准的示例为或 如今,领先的编码标准是UNICODE,它有多种风格。使用可变长度方案,编码用于表示8位字节上的数千个unicode字符:
- ascii字符(即0x00到0x7F)在单个字节上编码李>
- 所有其他字符按2到4字节编码李>
wchar\u t
/win\u t
(需要头wchar.h
)而不是char
/int
,并使用getwc()
/而不是getc()
/putc()
。如果在您的环境中sizeof(wchar\u t)
为4,则您将能够使用unicode,只需使用宽字符和宽库函数,而不是K&R中提到的普通函数。但是如果
sizeof(wchar\u t)
较小(例如2),您可以正确使用较大的unicode子集,但在某些情况下仍可能遇到对齐问题 与注释中一样,您的字符串可能是用UTF-8编码的。这意味着一些字符,包括您提到的字符,使用了多个字节。如果您只是通过计算字节数来确定输出的宽度,那么您的计算值可能太大
要正确确定具有多字节字符的字符串中的字符数,请使用函数,如
如果要逐字符计数,可以使用查找字符串中第一个字符的字节数
这当然超出了K&R书的范围。它是在使用多字节字符之前编写的。我猜您的字符串是在中编码的,其中多字节代码点中第一个字节之后的所有字节都遵循模式10xxxxxx
。在计算长度时忽略这些字节,并确保不会分解多字节序列。希望您不会处理分解字符(其中变音符号与基本字符分开)。使用表情符号的属性处理表情符号也是分解字符主题的一种变体。接下来是有趣的时刻。欢迎来到Stack Overflow。请尽快阅读这两页。我们将帮助您修复代码,这些代码显示了解决问题的诚实尝试,并描述了您遇到的问题。如果没有代码,您的问题可能会被认为“过于宽泛”或“因为缺少MCVE()”而脱离主题。请特别阅读关于grapheme群集的内容。当然,您完全正确地使用了mbrlen()
!但是K&R的第一章实际上是关于基础的。它使用的唯一库函数是基本的I/O函数,计数字符和行是通过循环来处理的。我试图理解这个函数,但做不到。随着我逐渐熟悉指针和C语言,我一定会尝试一下。谢谢你的回答。我可以问一下c&0xC0==0x80
条件意味着什么吗?二进制中c&0xC0==0x80
0xC0
的UV是1100 0000
<代码>&
确保存在0的所有位都被清除为0(K&R关于位逻辑运算的第2.9章)。因此,如果将c
的二进制表示形式设置为xyzzz
,则c&0xC0
将导致XY00 0000
。二进制中的0x80是1000 0000
。因此c&0xC0==0x80
为真,当且仅当二进制中的c
类似于10zzzzzz
。如果查看,您会注意到只有编码为10xx xxxx
的bute才是多字节编码的后续字节。