std::regex 的行为不一致

2024-05-27

我有以下问题:

  • std::regex如果我传递结果,行为会有所不同boost::filesystem::path::string()vs 将结果存储在中间字符串变量中。第一个将返回一个被截断的匹配,并且稍后不被接受std::stoull(抛出 invalid_argument 异常),而第二个则完美运行。

请参阅以下命令来详细解释该问题:

[nix-shell:~]$ ls -l foo
total 0
-rw-r--r-- 1 amine users 0 Aug 10 16:55 008
-rw-r--r-- 1 amine users 0 Aug 10 15:47 2530047398992289207

[nix-shell:~]$ cat test-1.cpp
#include <iostream>
#include <regex>
#include <string>
#include <boost/filesystem.hpp>

int main() {
  std::regex expression{R"(([0-9]+))"};
  boost::filesystem::path cacheDir("/home/amine/foo");
  for (const auto& entry : boost::filesystem::directory_iterator{cacheDir})
  {
      std::smatch match;
      auto result = std::regex_match(entry.path().filename().string(), match, expression);
      std::cout << "Result: " << result << std::endl
        << "Length: " << match[1].length() << std::endl
        << "Match: " << match[1] << std::endl
        << "Filename: " << entry.path().filename().string() << std::endl
        << std::endl;

      std::stoull(match[1], 0);
  }
  return 0;
}
[nix-shell:~]$ g++ -o test1 test-1.cpp -lboost_filesystem -O0 -g

[nix-shell:~]$ ./test1
Result: 1
Length: 19
Match: 98992289207
Filename: 2530047398992289207

terminate called after throwing an instance of 'std::invalid_argument'
  what():  stoull
Aborted

[nix-shell:~]$ cat test-2.cpp
#include <iostream>
#include <regex>
#include <string>
#include <boost/filesystem.hpp>

int main() {
  std::regex expression{R"(([0-9]+))"};
  boost::filesystem::path cacheDir("/home/amine/foo");
  for (const auto& entry : boost::filesystem::directory_iterator{cacheDir})
  {
      std::smatch match;
      auto what = entry.path().filename().string();
      auto result = std::regex_match(what, match, expression);
      std::cout << "Result: " << result << std::endl
        << "Length: " << match[1].length() << std::endl
        << "Match: " << match[1] << std::endl
        << "Filename: " << entry.path().filename().string() << std::endl
        << std::endl;

      std::stoull(match[1], 0);
  }
  return 0;
}
[nix-shell:~]$ g++ -o test2 test-2.cpp -lboost_filesystem -O0 -g

[nix-shell:~]$ ./test2
Result: 1
Length: 19
Match: 2530047398992289207
Filename: 2530047398992289207

Result: 1
Length: 3
Match: 008
Filename: 008

所以我的问题是:

  • 为什么结果是std::regex直接使用时会被截断boost::filesystem::path::string().
  • 让我们假设如果匹配变量中的结果被截断就可以了,为什么会这样呢?std::stoull抛出异常吗?

不幸的是,你掉进了陷阱。在 C++11 中的重载std::regex_match你打电话的是

template< class STraits, class SAlloc, 
          class Alloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT,STraits,SAlloc>& s,
                  std::match_results<
                      typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
                      Alloc
                  >& m,
                  const std::basic_regex<CharT,Traits>& e,
                  std::regex_constants::match_flag_type flags = 
                      std::regex_constants::match_default );

因为它需要一个const& to a std::string您可以向它传递一个临时字符串。对你来说不幸的是std::regex_match不适用于临时字符串。这就是为什么你会出现意想不到的行为。您尝试引用超出范围的数据。

C++14 通过添加解决了这个问题

template< class STraits, class SAlloc, 
          class Alloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT,STraits,SAlloc>&&,
                  std::match_results<
                      typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
                      Alloc
                  >&,
                  const std::basic_regex<CharT,Traits>&,
                  std::regex_constants::match_flag_type flags = 
                      std::regex_constants::match_default ) = delete;

所以你不能再传递临时字符串。

如果您不能使用 C++14,那么您需要确保没有将临时字符串传递给std::regex_match

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::regex 的行为不一致 的相关文章

  • 编译时运算符

    有人可以列出 C 中可用的所有编译时运算符吗 C 中有两个运算符 无论操作数如何 它们的结果始终可以在编译时确定 它们是sizeof 1 and 2 当然 其他运算符的许多特殊用途可以在编译时解决 例如标准中列出的那些整数常量表达式 1 与
  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • 不想保留一对一的实体

    假设我有两节课Employee and Department In Employee我已经写了 OneToOne fetch FetchType EAGER cascade CascadeType ALL JoinColumn name d
  • 使用 Parsec 解析正则表达式

    我正在尝试通过实现一个小型正则表达式解析器来学习秒差距 在 BNF 中 我的语法类似于 EXP EXP LIT EXP LIT 我尝试在 Haskell 中实现这一点 expr try star lt gt try litE lt gt l
  • django 创建多类型用户的最佳方法

    我想在 django 中创建多个用户 我想知道哪种方法是最好的 class Teachers models Model user models ForeignKey User is teacher models BooleanField d
  • 将资源文件链接到 Laravel4 中的视图

    您好 我是新手 正在学习 laravel 4 创建应用程序 我正在尝试使用 laravel Blade 将 twitter bootstrap3 文件链接到视图 我安装了一个新的 laravel 应用程序文件夹 为了从 url 路径中删除
  • 如何在lxml,Python中将<转换为<?

    有一个xml文件
  • 手动排除sbt中的一些测试类

    我通常在 CI 中执行以下命令 清理更新编译测试发布 但是 我想从 sbt 命令行中排除 1 个 或几个 测试类 我怎样才能做到这一点 我不想更改我的代码以使用忽略等 两种可能的选择 test only See http www scala
  • 运行 shell 命令并将输出发送到文件?

    我需要能够通过 php 脚本修改我的 openvpn 身份验证文件 我已将我的 http 用户设置为免通 sudoer 因为这台机器仅在我的家庭网络中可用 我目前有以下命令 echo shell exec sudo echo usernam
  • 为什么 Cassandra 客户端在生产中没有 epoll 时会失败? [复制]

    这个问题在这里已经有答案了 当我在本地运行服务时 我收到一条警告 指出 epoll 不可用 因此它使用 NIO 很公平 当我将其部署到 Kubernetes 中时 我得到了以下信息 这导致服务无法运行 2017 03 29T19 09 22
  • 找出段落中出现的单词

    sentence Alice was not a bit hurt and she jumped up on to her feet in a moment words Alice jumped played 我可以使用filterpyth
  • APACHE POI 从 Java 中的 Excel 获取精确的字体颜色

    在 Excel 工作表中 如何使用 Java 中的 Apache POI 获取准确的字体颜色值 我试图通过使用来获取字体颜色 org apache poi ss usermodel Font f book getFontAt style g
  • obj[] 和 string[] 作为参数

    我在用Microsoft FSharp Reflection FSharpValue MakeUnion这需要一个Reflection UnionCaseInfo and an obj 可以为空 作为参数 但是 我得到了Type misma
  • 创建新类别的优点和缺点是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 这可能是一个非常基本的问题 但这是我在学习更多有关 Actionscript 3 的过程中实际遇到的问题 然而 我的第一个问题非常笼统 什么时候
  • 何时在 Gevent 中使用线程池

    我注意到 Gevent 有线程池对象 有人可以向我解释何时使用线程池以及何时使用常规池吗 gevent threadpool 和 gevent pool 有什么区别 当你有一段需要很长时间运行 几秒钟 并且不会导致 greenlet 切换的
  • AVAudioSessionPortBluetoothHFP、A2DP 和 LE 有什么区别?

    Apple 中记录了三种不同的蓝牙相关音频端口类型AVAudioSessionPort 描述 https developer apple com library ios documentation AVFoundation Referenc
  • 如何在SQL中查找单元格中的重复单词

    我有一个名为 situation 和 entityid 的列 Entityid Situation 1234 In the the world of of 3456 Total universe is is a 任何人都可以给我查询以找到这
  • Time 方法在另一个线程中执行并在超时时中止

    您好 我正在尝试异步运行方法 以便计算持续时间并在超过超时时取消该方法 我尝试使用异步和等待来实现这一点 但没有运气 也许我过度设计了这个 任何输入都会受到赞赏 应该注意的是 我无法更改接口 TheirInterface 因此得名 到目前为
  • 云存储 API 的错误导入“系统调用”

    我正在按照以下说明进行操作https cloud google com appengine docs go googlecloudstorageclient download开始将一些代码从现已弃用的文件 API 迁移到新的 Cloud S
  • 了解C/C++中函数调用的堆栈框架? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我也是 C C 和汇编语言的新手 这
  • 使 .git 目录 web 不可访问

    我有一个网站 我使用 github 闭源 来跟踪更改和更新网站 唯一的问题是 git 目录似乎可以通过网络访问 我怎样才能停止这个并且仍然能够使用 git 我应该使用 htaccess 吗 我应该更改 git 的权限吗 把这个放在一个 ht
  • std::regex 的行为不一致

    我有以下问题 std regex如果我传递结果 行为会有所不同boost filesystem path string vs 将结果存储在中间字符串变量中 第一个将返回一个被截断的匹配 并且稍后不被接受std stoull 抛出 inval