【问题标题】:Strangeness with special characters in C-strings and unprintable ASCIIC 字符串中的特殊字符和不可打印的 ASCII 的奇怪之处
【发布时间】:2020-07-22 14:14:40
【问题描述】:

我需要将一个 c++ 字符串复制到一个 char 数组中,然后对其进行解码。 char 数组不需要以空值结尾。由于编码的性质,许多字符是不寻常的,有些是不可打印的,这会导致问题。

这是 C++ 字符串打印的内容: std::cout << myString; 输出:

mw\22ypwr\`himg 0few1nvnl

通过执行以下操作将其转换为char []

char * m = new char[myString.size() + 1];
strcpy(m, myString.c_str());

m* 的长度为 24,不正确。它无法正确解码。以下char [] 可以正确解码:

char m2 [] = "mw\22ypwr`himg 0few1nvnl";

请注意,这是通过复制字符串的输出创建的。但是,这个 c 字符串的长度只有 22,而不是 24。此外,打印它有以下结果:

std::cout << m;

输出:

mwypwr`himg 0few1nvnl

请注意,\22 已消失。但是,这并不像在将字符串转换为char[] 之前将其从字符串中删除那么简单。遍历 ASCII 值显示有一个十进制操作码为 18 的字符,而 \22 曾经是该字符。该字符不打印。

ASCII 值作为十进制:

109 119 18 121 112 119 114 96 104 105 109 103 32 48 102 101 119 49 110 118 110 108 

为什么\22 会被转换为 ASCII 字符 18?如何从具有文字 \22 的 C++ 字符串构造正确的、可解码的 C 字符串?我需要能够为大量可能未知的编码字符串执行此操作,因此我不希望在不知道为什么会发生这种情况的情况下手动将\22 替换为 ASCII 18。

【问题讨论】:

  • 为什么 \22 会被转换... -- 也许是八进制?八进制 22 是十进制 18。
  • char 数组不需要空终止,那么您不能使用strcpy,因为它期望是一个有效的\0-终止字符串。
  • 我不确定你想要什么行为。你想让它打印和 C++ 输出一样吗?
  • @Pablo 你是对的,strcpy 然后不能被使用。但是您可以看到我如何使用strcpy 与输入表单myString.c_string() 一起使用,这将产生一个有效的c-string。
  • 您的字符串也包含octal characters。这就是您获得转化的原因。

标签: c++ c string ascii non-ascii-characters


【解决方案1】:

如果 c++ 字符串不是以零结尾的,那么这将不起作用

strcpy(m, myString.c_str());

strcpy 复制到零,使用 memcpy 代替

【讨论】:

    【解决方案2】:

    字符串包含表示octal characters的转义序列。

    "mw\22ypwr\...other characters..."

    \22 是十进制 18 的八进制,因此当您显示每个字符的数字版本时会看到输出。

    【讨论】:

      猜你喜欢
      • 2011-01-16
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多