我想在K& R书中做 练习1-22 。它要求在字符串中预定义数量的字符后折叠长行(即进入新行)。
当我测试程序并且它运行良好时,但我看到有些线条比他们应该更早地“折叠”。我注意到出现了特殊字符的行,例如:
öşçğ
所以,我的问题是,如何确保使用相同的最大长度打印线条是否有多个字符?
答案 0 :(得分:1)
您的代码会发生什么?
K& R是在所有角色都在一个字母上编码的时间写的。此类编码标准的示例为ASCII或ISO 8859。
如今,领先的编码标准是UNICODE,它有多种口味。 UTF-8编码用于表示8位字节上的数千个unicode字符,使用可变长度方案:
因此列表中的letter ö和其他符号被编码为2个连续字节。不幸的是,标准C库和K& R的算法不管理变量编码。因此,每个特殊字符都计为两个,以便您的算法被欺骗。
如何解决?
没有简单的方法。您必须区分内存中字符串的长度以及显示字符串时的长度。
我可以为您提出一个使用编码方案属性的技巧:每当计算字符串的显示长度时,只需忽略符合条件c& 0xC0 == 0x80的内存中的字符c。
另一种方法是使用宽字符wchar_t
/ win_t
(需要标题wchar.h
)而不是char
/ int
并使用{{1} } / getwc()
代替putwc()
/ getc()
。如果您的环境putc()
为4,那么您将能够使用宽字符和宽库函数而不是K& R中提到的常规函数来使用unicode。但是如果是的话
sizeof(wchar_t)
较小(例如2),您可以使用更大的unicode子集正常工作,但在某些情况下仍然可能遇到对齐问题。
答案 1 :(得分:0)
在评论中,您的字符串可能以UTF-8编码。这意味着某些字符(包括您提到的字符)使用多个字节。如果只计算字节数以确定输出的宽度,则计算值可能太大。
要正确确定包含多字节字符的字符串中的字符数,请使用mbrlen(3)等函数。
如果您要为字符计算字符,可以使用mbrtowc(3)查找字符串中第一个字符的字节数。
这当然超出了K& R书的范围。它是在使用多字节字符之前编写的。