gpt4 book ai didi

C++ istream、getline、二进制文件、正则表达式和字符串的意外行为

转载 作者:行者123 更新时间:2023-12-02 10:12:45 29 4
gpt4 key购买 nike

我正在使用一个结合了文本和二进制格式(有时只是纯文本)的文件。所以我决定将文件作为二进制文件打开并试一试。但是,当我以后使用正则表达式时(表示内存损坏的那种问题),我会遇到意想不到的行为:
(编辑有一个最小的例子)

#include <string>
#include <iostream>
#include <fstream>
#include <regex>
#include <ios>

struct FortranFormat {
std::string itemsPerRow;
std::string type;
std::string numberOfCharacters;
};

class XXXParserException: virtual public std::runtime_error {
using runtime_error::runtime_error;
};


std::string parseSection(const std::string &line) {
return line.substr(16, std::string::npos );
}


FortranFormat parse(const std::string& expression) {
const std::regex getItemsExpr("\\(([0-9]+)([A|a|I|i|F|f|E|e])([0-9]+)\\)");

std::cout << "expression: " << expression << std::endl;

std::smatch elements;
if (std::regex_match(expression, elements, getItemsExpr)) {

return {elements[1].str(),elements[2].str(),elements[3].str()};
} else {
throw XXXParserException("The expression " + expression + " is not a recognized Fortran Format.");
}
}

void main() {

std::ifstream fb;
fb.open("example.txt", std::ios::binary); // remove the binary flag, and it works
std::string line;
getline(fb, line);
std::cout << "line: " << line << std::endl;
std::string formula = parseSection(line);

auto format = parse(formula);

std::cout << "format: " << format.type << std::endl;
}
打印品有正确的信息:
line: *VALUES        6(5E16.8)
expression: (5E16.8)
(即使是异常文本也被破坏了,只有最后一部分:
“不是公认的 Fortran 格式。”)
所以,更多的是出于好奇:我是否在做一些根本上错误的事情,从而破坏了内部的某些东西?这是否可以归因于编译器(VS2015)?
仅供引用,我将尝试“在格式之间跳转方法”来解决问题(保存当前位置,根据需要以文本或二进制文件的形式关闭和打开,恢复位置),但我只想了解我的当前位置可能有什么问题方法。

最佳答案

有两点需要考虑:
在文本模式下,\n被作为 native EOL 组合处理(因此在 Windows 上为 \r\n)。在二进制模式下没有这样的事情,所以 \n始终是换行符,仅此而已。您要求在 \n 之前阅读尽可能多的文本。 ,在 Windows 上留下 \r在字符串的末尾。
然后, std::regex_match 要求整个字符串匹配正则表达式。您的正则表达式不允许在字符串末尾有额外的空格,因此它不匹配。 std::regex_search 将返回 true在该输入上,因为没有最后一个字符的子字符串与模式匹配。

提示:Raw string literals使正则表达式更容易,因为您不必转义文字(现在很容易在 regex101 中调试!):

const std::regex getItemsExpr(R"eos(\(([0-9]+)([A|a|I|i|F|f|E|e])([0-9]+)\))eos");

关于C++ istream、getline、二进制文件、正则表达式和字符串的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62958243/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com