如何使用相同长度打印带有或不带多字符的字符串?

时间:2018-01-13 19:30:27

标签: c character-encoding

我想在K& R书中做 练习1-22 。它要求在字符串中预定义数量的字符后折叠长行(即进入新行)。

当我测试程序并且它运行良好时,但我看到有些线条比他们应该更早地“折叠”。我注意到出现了特殊字符的行,例如:

  

öşçğ

所以,我的问题是,如何确保使用相同的最大长度打印线条是否有多个字符?

2 个答案:

答案 0 :(得分:1)

您的代码会发生什么?

K& R是在所有角色都在一个字母上编码的时间写的。此类编码标准的示例为ASCIIISO 8859

如今,领先的编码标准是UNICODE,它有多种口味。 UTF-8编码用于表示8位字节上的数千个unicode字符,使用可变长度方案:

  • ascii字符(即0x00到0x7F)在单个字节上编码。
  • 所有其他字符都以2到4个字节进行编码。

因此列表中的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书的范围。它是在使用多字节字符之前编写的。