【问题标题】:std::string::find returns wrong answerstd::string::find 返回错误答案
【发布时间】:2018-10-03 12:47:23
【问题描述】:

有一些关于 std::string::find 的帖子(如 this one herethis one too)但我的情况有些不同:

#include <string>
#include <stdio.h>

int main(int argc, char **argv)
{
    std::string haystack = "ab\\x10c\200\\x00\\x00\\x00\\x00";
    std::string needle   = "\\x00";

    printf("first index is %d\n",(int) haystack.find(needle));

    return 0;
}

根据值我想知道为什么返回 8:

我猜 "\200" 算作 1 个字符 (?) 我可以让find 也将"\\x10" 视为1 个字符吗?

【问题讨论】:

  • 问题不清楚
  • haystack 和 needle 是如何定义的?你是如何初始化它们的?
  • @drorco,它们是发送给某个函数的参数......这一行来自函数体......
  • 我已将示例修复为自包含且可重现

标签: c++ find hex stdstring


【解决方案1】:

一切正常

+---+---+---+---+---+---+---+------+---+---+---+---+
| a | b | \ | x | 1 | 0 | c | \200 | \ | x | 0 | 0 |
+---+---+---+---+---+---+---+------+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |   7  | 8 |   |   |   |
+---+---+---+---+---+---+---+------+---+---+---+---+

\\ 变成一个字符 \。看来您想要 \xNN 和一个 \

即使您将文字字符串中的\\ 替换为\,它也不会起作用,因为第一个\x00 将被视为终止零,之后的其他字符将被忽略。我猜想字符串的初始化应该是这样的:

std::string haystack = {'a', 'b', '\x10', 'c', '\200', '\x00', '\x00', '\x00', '\x00'};
std::string needle   = {'\x00'};

程序将输出 5。

【讨论】:

    【解决方案2】:

    \200 1 个字符。请参阅list of escape sequences。我在这里包括了相关的:

    Escape sequence    Description                    Representation
    \\                 backslash                      byte 0x5c in ASCII encoding
    \nnn               arbitrary octal value          byte nnn
    \xnn               arbitrary hexadecimal value    byte nn
    

    \200 是一个值为 128 的单个字符(八进制的 200 是十进制的 128)。

    \\x10 是 4 个字符:\\(反斜杠)、x10。如果您希望它作为单个字符,则不要转义反斜杠 - \x10 是一个值为 16 的单个字符(十六进制的 10 是十进制的 16)。

    【讨论】:

      【解决方案3】:

      \200零宽度非连接器 之一。那是一个以 UTF-8 编码的 unicode 字符。

      例如-

      0x2e, 0x80, 0x8c (or in base 8, \342, \200, \214)
      

      这是您的字符串的索引方式:

      0个
      1个
      2 \
      3 x
      4 1
      5 0
      6c
      7 �
      8 \
      9 x
      10 0
      11 0
      12 \
      13 x
      14 0
      15 0
      16 \
      17 x
      18 0
      19 0
      20 \
      21 x
      22 0
      23 0

      查看7th 索引。这将消除您的疑虑。

      如果您想将\\x10 读取为单个字符,请使用\x10,它将其视为十六进制数字。

      【讨论】:

        猜你喜欢
        • 2022-08-18
        • 1970-01-01
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        • 1970-01-01
        • 2014-12-04
        • 1970-01-01
        • 2022-08-17
        相关资源
        最近更新 更多