我正在尝试在 K&R 书中进行练习 1-22。它要求在字符串中预定义数量的字符之后折叠长行(即进入新行)。
当我测试该程序时,它运行良好,但我发现有些行比应有的更早“折叠”。我注意到这是出现特殊字符的行,例如:
ö ş ç ğ
所以,我的问题是,如何确保打印的行具有相同的最大长度,无论是否包含多字符?
最佳答案
您的代码中发生了什么?
K&R 是在所有字符都编码在一个字符上的时代编写的。此类编码标准的示例是 ASCII或ISO 8859 。
当今领先的编码标准是 UNICODE,它有多种风格。 UTF-8编码用于表示 8 位字节上的数千个 unicode 字符,使用可变长度方案:
- ascii 字符(即 0x00 到 0x7F)在单个字节上编码。
- 所有其他字符均以 2 到 4 个字节进行编码。
所以 letter ö列表中的其他内容被编码为 2 个连续字节。不幸的是,标准 C 库和 K&R 算法不管理变量编码。所以你的每个特殊字符都被算作两个,这样你的算法就被欺骗了。
如何解决?
没有简单的方法。您必须区分内存中字符串的长度和显示字符串时的长度。
我可以向您推荐一个利用编码方案属性的技巧:每当您计算字符串的显示长度时,只需忽略内存中符合条件 c&0xC0==0x80 的字符 c 即可。
另一种方法是使用宽字符 wchar_t
/win_t
(需要 header wchar.h
)而不是 char
/int
并使用getwc()
/putwc()
而不是getc()
/putc()
。如果在您的环境中sizeof(wchar_t)
是 4 那么您将能够仅使用宽字符和宽库函数而不是 K&R 中提到的普通函数来使用 unicode。然而如果
sizeof(wchar_t)
较小(例如 2),您可以正确使用更大的 unicode 子集,但在某些情况下仍然可能遇到对齐问题。
关于c - 如何打印具有或不具有多字符的相同长度的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48243540/