C++;:分析带有拆分的日志,但一个条目可以有多行 我开始学习C++,我现在的项目应该扩展我的知识,使用文件,拆分,最后在VARCHAR字符串上做一个ReXEP。
问题是: 我有一个日志文件,其中包含如下数据C++;:分析带有拆分的日志,但一个条目可以有多行 我开始学习C++,我现在的项目应该扩展我的知识,使用文件,拆分,最后在VARCHAR字符串上做一个ReXEP。,c++,regex,split,C++,Regex,Split,问题是: 我有一个日志文件,其中包含如下数据 <date> <time> <username> (<ip:port>) <uuid> - #<id> "<varchar text>" 因此,我从以下内容开始,但我现在被困在如何将带有\n的行放入字符串中。如何以正确的方式解决此问题,而无需执行不必要的步骤(如多次拆分),以及如何定义完整行(即使其中包含一些\n)的停止位置 使用fin.ignore(80'\n')
<date> <time> <username> (<ip:port>) <uuid> - #<id> "<varchar text>"
因此,我从以下内容开始,但我现在被困在如何将带有\n
的行放入字符串中。如何以正确的方式解决此问题,而无需执行不必要的步骤(如多次拆分),以及如何定义完整行(即使其中包含一些\n
)的停止位置
使用fin.ignore(80'\n')代码>,\n
s被忽略,但这意味着我只有一行。。。#前短文本,后大字符串:-|
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
std::vector<std::string> split(std::string str, char seperator) {
std::vector<std::string> result;
std::string::size_type token_offset = 0;
std::string::size_type seperator_offset = 0;
while (seperator_offset != std::string::npos) {
seperator_offset = str.find(seperator, seperator_offset);
std::string::size_type token_length;
if(seperator_offset == std::string::npos) {
token_length = seperator_offset;
} else {
token_length = seperator_offset - token_offset;
seperator_offset++;
}
std::string token = str.substr(token_offset, token_length);
if (!token.empty()) {
result.push_back(token);
}
token_offset = seperator_offset;
}
return result;
}
int main(int argc, char **argv) {
std::fstream fin("input.dat");
while(!fin.eof()) {
std::string line;
getline(fin, line, ';');
fin.ignore(80, '\n');
std::vector<std::string> strs = split(line, ',');
for(int i = 0; i < strs.size(); ++i) {
std::cout << strs[i] << std::endl;
}
}
fin.close();
return 0;
}
#包括
#包括
#包括
#包括
std::vector split(std::string str,字符分隔符){
std::向量结果;
std::string::size\u type token\u offset=0;
std::string::size\u type分隔符\u offset=0;
while(分隔符_offset!=std::string::npos){
separator_offset=str.find(separator,separator_offset);
std::string::size\u type token\u length;
if(分隔符_偏移==std::string::npos){
标记长度=分隔符偏移量;
}否则{
令牌\u长度=分隔符\u偏移-令牌\u偏移;
分隔符_offset++;
}
std::string token=str.substr(token\u offset,token\u length);
如果(!token.empty()){
结果。推回(令牌);
}
令牌\u偏移=分隔符\u偏移;
}
返回结果;
}
int main(int argc,字符**argv){
标准::fstream fin(“input.dat”);
而(!fin.eof()){
std::字符串行;
getline(fin,line,“;”);
忽略(80,“\n”);
std::vector strs=拆分(行“,”);
对于(int i=0;i Std::CUT< P>没有输入的C++库函数,像这样吞咽输入。<代码> STD::GETLION/CODE读取下一行文本,直到下一行换行符(默认)。就是这样。<代码> STD::GETLION/CODE>不做任何进一步的检查,除了输入。
我将为您推荐以下方法
- 初始化表示刚刚读取的整个逻辑行的缓冲区
- 使用
std::getline
()读取下一行输入,并将该行附加到输入缓冲区
- 计算缓冲区中的引号字符数
- 引号的数量是偶数吗?停止。如果引号字符计数是奇数,请在缓冲区中添加一个换行符,然后返回并读取另一行输入
这里当然有一些明显的优化,但是这应该是一个好的开始。
< P>没有输入的C++库函数来像这样吞咽输入。<代码> STD::GETLION/CODE>读取下一行文本,直到下一个新行字符(默认情况下).就是这样。std::getline
没有对输入做任何进一步的检查,除此之外
我将为您推荐以下方法
- 初始化表示刚刚读取的整个逻辑行的缓冲区
- 使用
std::getline
()读取下一行输入,并将该行附加到输入缓冲区
- 计算缓冲区中的引号字符数
- 引号的数量是偶数吗?停止。如果引号字符计数是奇数,请在缓冲区中添加一个换行符,然后返回并读取另一行输入
当然,这里可以进行一些明显的优化,但这应该是一个良好的开端。您能给我们提供()的格式吗
?结束标记是什么?我在示例中没有看到
。请参阅第二个代码引用框。它包含一个示例日志。uuid就在哈希之后。我的问题是,日志des在varchar文本周围没有任何可靠的结束双引号的结束标记instand。谢谢。没有哈希。我可以看到日期和时间,用户名主机:端口,但我看到的是#id后跟“text”。请指出散列和uuid的位置。请从您的示例中获取准确值。您能给我们提供()
?结束标记是什么?我在示例中没有看到
。请参阅第二个代码引用框。它包含一个示例日志。uuid就在哈希之后。我的问题是,日志des在varchar文本周围没有任何可靠的结束双引号的结束标记instand。谢谢。没有哈希.我可以看到日期和时间,用户名主机:端口,但我可以看到#id后跟“文本”。请指出散列和uuid的位置。请使用示例中的精确值。是的,这可能是一个很好的开始。通常具有\n的行不会以双引号结尾,但为了安全起见,我将检查每一行是否以日期开头。谢谢。是的,这可能是一个很好的开始。通常具有\n的行不是以双引号结尾,但为了安全起见,我会检查每一行是否以日期开头,非常感谢
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
std::vector<std::string> split(std::string str, char seperator) {
std::vector<std::string> result;
std::string::size_type token_offset = 0;
std::string::size_type seperator_offset = 0;
while (seperator_offset != std::string::npos) {
seperator_offset = str.find(seperator, seperator_offset);
std::string::size_type token_length;
if(seperator_offset == std::string::npos) {
token_length = seperator_offset;
} else {
token_length = seperator_offset - token_offset;
seperator_offset++;
}
std::string token = str.substr(token_offset, token_length);
if (!token.empty()) {
result.push_back(token);
}
token_offset = seperator_offset;
}
return result;
}
int main(int argc, char **argv) {
std::fstream fin("input.dat");
while(!fin.eof()) {
std::string line;
getline(fin, line, ';');
fin.ignore(80, '\n');
std::vector<std::string> strs = split(line, ',');
for(int i = 0; i < strs.size(); ++i) {
std::cout << strs[i] << std::endl;
}
}
fin.close();
return 0;
}