c - 如何打印具有或不具有多字符的相同长度的字符串?

标签 c character-encoding

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

当我测试该程序时,它运行良好,但我发现有些行比应有的更早“折叠”。我注意到这是出现特殊字符的行,例如:

ö ş ç ğ

所以,我的问题是,如何确保打印的行具有相同的最大长度,无论是否包含多字符?

最佳答案

您的代码中发生了什么?

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 (需要 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/

相关文章:

在 C 中更改二进制地址中的一个给定位

c - 对结构中的特定元素进行排序

Emacs:当前缓冲区的编码系统

java - 来自自定义标签和 IllegalStateExceptions 的 RequestDispatcher.include()

html 元标记在其他页面中不起作用

php - Mysql插入被奇怪的字符编码截断的文本数据

javascript - jQuery(form).serialize() 失败,返回 "URIError: malformed URI sequence"

C - 神秘的线程段错误

C 如何比较字符串是否为十六进制 0d0a

c - 为什么 int 而不是 unsigned int 用于 C 和 C++ for 循环?