如何在普通C89中读取字符长度的UTF-8字符串?

Ale*_*ysh 6 c unicode c89

我正在用纯C89编写一个自定义的跨平台简约TCP服务器.(但我也会接受POSIX特定的答案.)

服务器使用UTF-8字符串,但从不查看它们.它将所有字符串视为不可变二进制blob.

但是现在我需要接受来自客户端的UTF-8字符串,它不知道如何以字节为单位计算它们的大小.客户端只能以字符传输字符串长度.(更新:客户端是在JavaScript中,"字符长度"实际上是任何String.length()返回.我假设它是实际的UTF-8字符,而不是其他东西.)

我不想在我的小服务器上添加大量依赖项.是否有一种强大而简洁的方式来读取此数据报?(为了这个问题,让我们说它是从中读取的FILE *.)

U<CRLF>       ; data type marker (actually read by dispatching code)
<SIZE><CRLF>  ; UTF-8 string size in characters
<DATA><CRLF>  ; data blob
Run Code Online (Sandbox Code Playgroud)

例:

U
7
??????!
Run Code Online (Sandbox Code Playgroud)

更新:

一批数据可以包含多个数据报,因此近似读取不起作用,我需要读取确切数量的字符.

实际的UTF-8数据可能包含任何字符,因此我不能选择一个字符作为终结符 - 我不希望在数据中转移它.

Jon*_*Jon 9

根据这里的信息,写一个UTF-8"读者"非常容易; UTF-8的设计使得像这样的任务变得简单.

从本质上讲,您开始阅读字符,直到您阅读客户告诉您的字符数.您知道在给定UTF-8编码定义的情况下,您已经阅读了整个字符,具体而言:

如果字符仅由一个字节编码,则高位为0,其他位给出代码值(在0..127范围内).如果字符由多个字节的序列编码,则第一个字节的前导'1'位与序列中的总字节数一样多,后跟一个'0'位,后续字节全部标记通过领先的"10"位模式.

  • 如果你自己动手,你需要非常小心,不要误解无效的字节序列,就好像它们是UTF-8一样,特别是如果长度稍后有效则很重要...... (3认同)
  • 这是我提到的文件:http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt (2认同)

Ale*_*ysh 0

这看起来正是我需要的东西。希望我早点找到它:

http://bjoern.hoehrmann.de/utf-8/decoder/dfa/