首页 > 解决方案 > 正则表达式在 23 个字符处停止工作,但前提是我传入字符串文字

问题描述

我一直试图缩小我注意到的这种非常奇怪的行为。这是代码。

#include <iostream>
#include <regex>

struct Scanner {
  std::string::const_iterator read_head;
  std::string::const_iterator eof;

  Scanner(std::string const& program) {
    read_head = program.cbegin();
    eof = program.cend();
  }
};

bool scan(Scanner const& scanner) {
  using std::regex_constants::match_continuous;
  static std::smatch match;

  std::regex regex = std::regex("a+");
  return std::regex_search(scanner.read_head, scanner.eof, match, regex, match_continuous);
}

int main() {
  std::string str1 = "aaaaaaaaaaaaaaaaaaaaaa"; // 22 a's
  std::string str2 = "aaaaaaaaaaaaaaaaaaaaaaa"; // 23 a's
  Scanner s1(str1);
  Scanner s2(str2);
  Scanner s3("aaaaaaaaaaaaaaaaaaaaaa"); // 22 a's
  Scanner s4("aaaaaaaaaaaaaaaaaaaaaaa"); // 23 a's

  bool token1_found = scan(s1);
  bool token2_found = scan(s2);
  bool token3_found = scan(s3);
  bool token4_found = scan(s4);

  std::cout << std::boolalpha << token1_found << std::endl;
  std::cout << std::boolalpha << token2_found << std::endl;
  std::cout << std::boolalpha << token3_found << std::endl;
  std::cout << std::boolalpha << token4_found << std::endl;
}

我希望所有这四个都显示true,但奇怪的是,我得到:

true
true
true
false

如果我使用结构,它似乎只会这样做。我尝试编写一个执行相同操作的函数,但通过直接传入字符串或迭代器,并且在这些情况下一切都按预期运行(我没有得到这个莫名其妙的false)。

有人知道这里发生了什么吗?


编辑: 我试图解决这个问题,根据@Geoffroy 的说法,它Scanner没有获得字符串的所有权。这是我尝试过的:

struct Scanner {
  std::string program;
  std::string::const_iterator read_head;
  std::string::const_iterator eof;

  Scanner(std::string program) : program(program) {
    read_head = program.cbegin();
    eof = program.cend();
  }
};

但无济于事。有趣的是,当我这样做时,我得到

true
false
true
false

编辑2:

哦,但如果我改变

bool scan(Scanner const& scanner)

bool scan(Scanner scanner)

然后我得到

true
true
true
true

有谁知道为什么会这样?我假设s1-s4会一直存在到main.

标签: c++

解决方案


Scanner应该拥有它使用的字符串,否则您将使用迭代器来访问临时对象。

它在传递时有效str1并且str2对象仍然存在,但在字符串文字的情况下,它是未定义的行为。


推荐阅读