【问题标题】:parsing utf8 string from server response从服务器响应中解析 utf8 字符串
【发布时间】:2013-10-30 08:49:49
【问题描述】:

我在某些设备上实现了应用程序,该应用程序正在处理从服务器发送接收数据。 来自服务器的数据通常以这种形式出现:

"1;username;someInteger;"

解析很简单,我使用strtok 来从该字符串中检索单个值,例如:1usernamesomeInteger

但现在可能会出现服务器将 unicode 字符串作为username 发送给我的情况。

我认为一个好主意是使用编码为 UTF-8 字符串的用户名(对吗?)。你有什么建议 - 我应该如何从上面的字符串中解析它?例如,使用什么符号作为分隔符(例如,代替“;”),或者使用哪些函数从上面的字符串中提取 username

因为这是一些嵌入式设备,我想避免在那里安装一些第三方库(这可能甚至不可能),所以更“纯”的方式会更可取。

【问题讨论】:

  • 避免strtok。它不是线程安全的。请改用boost::split
  • @rightfold 避免使用boost 来简单地替换strtok()。这个太大了。请改用strtok_r()
  • @H2CO3:是的,就像我提到的那样,这是嵌入式设备 - 我还试图避免在那里安装一些大型第三方库(即使这可能也不确定)
  • @H2CO3 你看到strtok 源代码,还是为它生成的二进制代码?与“boost::split”相比,它“小”吗?
  • @Abyx 我的 cmets 都在哪里?至于你的问题:herestrtok() 的实现,这里是boost::algorithm::string::split() 使用的iter_split()。总而言之,strtok() 的 SLOC 比 boost 的要少,但它的优点是 1. 标准,2. 不需要包含巨大的标头,3. 它也可以在 C 中工作。

标签: c++ c


【解决方案1】:

字符 ';' 在 UTF-8 中与在 ASCII 中相同,因为两种编码中的前 127 个字符相同的。这意味着您仍然可以使用strtok';' 上进行拆分。

【讨论】:

  • 我听说 strtok 可能会“停止”,如果在它之间遇到“空终止字符” - 难道 Unicode 字符串在 strtok 的两个分隔符 (;) 之间包含一些字符将解释为空终止字符?
  • @dmcr_code no,多字节序列仅包含值 >= 128(或 都是 ASCII 码点。除了包含空字节的空字符外,没有代码点(请参阅stackoverflow.com/questions/6907297/can-utf-8-contain-zero-byte)。换句话说:如果 strtok 遇到一个空字节,它 零分隔符,没有别的。这同样适用于任何其他 ASCII 值:
  • 含义:; 也不能作为多字节序列的一部分找到,因此不会出现误报。
  • @Arne Mertz:好的,我明白了,我只是想知道字符串中可能会有一些非 ascii 字符,其代码值(代码点)是这样的,例如:45 00 - 然后 strtok 会将此符号的最后一个字节解释为空终止符,对吗? (但我认为你说这不可能)
  • @dmcr_code 是的,那不可能。 45 和 00 都不能是多字节序列(非 ASCII 码位)的一部分 - 它们只包含 > 80(十六进制)的值
【解决方案2】:

UTF8 的特点是您几乎不需要做任何事情。 ASCII 字符仍然会编码为与以往相同的 ASCII 字节,因此如果您继续使用分号分隔符,则根本无需执行任何操作。

【讨论】:

  • 我认为 strtok 可能会停止,如果在它之间遇到“空终止字符” - 难道 Unicode 字符串在 strtok 将解释为的两个分隔符 (;) 之间包含一些字符空终止字符?
  • 不:唯一的“空终止字符”是 ASCII 0,也就是 NUL。 UTF-8 编码不包含任何 NUL 字符,但 NUL 本身除外,这与普通 ASCII 一样。
猜你喜欢
  • 2019-07-18
  • 2013-08-05
  • 2021-06-03
  • 2023-03-27
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
相关资源
最近更新 更多