将文本文件 C++ 从特定行解析到特定行
Posted
技术标签:
【中文标题】将文本文件 C++ 从特定行解析到特定行【英文标题】:Parsing a text file C++ from specific line to specific line 【发布时间】:2019-12-15 12:22:48 【问题描述】:所以,我是 C++ 新手。我的任务是解析如下所示的文本文件:
RE002%%
RE002%%
RE002%%
RE002%%
RE002%%
RE004%on%
$GPGGA,124749.80,5543.3227107,N,03739.1366738,E,1,08,1.11,147.9635,M,14.4298,M,,*5C
$GPGSV,3,1,10,27,13,078,43,05,31,307,48,16,24,042,43,02,10,267,43*7D
$GPGSV,3,2,10,26,03,031,36,07,75,215,51,09,57,121,53,30,40,234,50*76
$GPGSV,3,3,10,23,29,117,46,04,36,114,46*70
$GPGGA,124749.90,5543.3227105,N,03739.1366737,E,1,08,1.11,147.9664,M,14.4298,M,,*54
RE005%off%
它连续几千行。我需要找到它在哪里写入 RE004%on% 并开始在这个循环中处理行,直到它找到 RE005%off% 并一遍又一遍地执行直到文件结束。我试图用 line.find 来做,但我很确定这是解决这个问题的错误方法
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
string line, dollar, star, Checksum;
float *t0 = NULL;
int tount = 0;
int k;
ifstream logs_("C:/Users/Olya/Desktop/LogGLO.txt");
ofstream tout("outLOGTime.txt");
ofstream pout("outLOGPot.txt");
if (logs_.is_open())
while(getline(logs_,line))
line.find("RE004%on%")
k = 0;
if
dollar = line.find_first_of('$');
star = line.find_first_of('*');
Checksum = line.substr(line, dollar, star - dollar);
for (size_t i = 0; i < Checksum.size(); i++)
if (line.substr(0,6) == "$GPGSV")
for (size_t i = 0, N = 7; i < line.size(); i++)
if (line[i] == ',') k++;
if(k == N)
pout << line.substr(i+1,2) << endl;
if ((N += 4) > 19) break;
logs_.close();
else
cout<<"File is not open"<<'\n';
tout.close();
pout.close();
return 0;
【问题讨论】:
【参考方案1】:很遗憾,您的描述非常不清楚。另外通过阅读您的代码,我真的无法理解您打算做什么。您编辑了文本并更改了描述。对我来说不是那么容易
但是,我做了一个有根据的猜测。 . .
我读取给定分隔符之间的所有数据,验证校验和并将行拆分为标记。最后,我将所有带有标记的行存储在一个向量中。然后我过滤一个特定的值并输出一列。
请学习并尝试理解。没那么复杂。
谢谢
#include <iostream>
#include <regex>
#include <vector>
#include <iterator>
#include <string>
#include <utility>
#include <algorithm>
#include <functional>
#include <numeric>
#include <fstream>
const std::regex re R"(\$(.*)\*[abcdefABCDEF\d]2)" ;
const std::regex delimiter "," ;
using Tokens = std::vector<std::string>;
std::tuple<bool, Tokens> checkString(const std::string& str)
// Return value of the function. Assume that string is not ok
std::tuple<bool, std::vector<std::string>> result(false, );
// We want to find a string in the given format
std::smatch sm;
if (std::regex_match(str, sm, re))
// OK, found. Validate checksum
if (std::string s = sm[1];std::stoul(str.substr(str.size() - 2), nullptr, 16) == std::accumulate(s.begin(), s.end(), 0U, std::bit_xor<unsigned char>()))
// Tokenize string
Tokens tokens(std::sregex_token_iterator(str.begin(), str.end(), delimiter, -1), );
// Build return value
result = std::make_tuple(true, std::move(tokens));
return result;
int main()
std::vector<Tokens> csvData;
// Open file and check if it is open
if (std::ifstream logs("r:\\LogGLO.txt"); logs)
// Shall we process text lines or not
bool processingActive false ;
// Read all lines of files
for (std::string line; std::getline(logs, line);)
// Check, if we should start or stio processing of the lines
if (line.substr(0, 9) == std::string("RE004%on%")) processingActive = true;
if (line.substr(0, 10) == std::string("RE005%off%")) processingActive = false;
// Check and read csv data
if (processingActive)
const auto [ok, data] = checkString(line);
if (ok) csvData.push_back(std::move(data));
// So, now we have read all csv data
// Show eight column of GPGSV data
for (const Tokens& t : csvData)
if (t[0] == "$GPGSV")
std::cout << t[7] << "\n";
return 0;
【讨论】:
非常感谢您编写这个程序,它的许多工作对我来说不是很清楚,因为我从未遇到过您使用的许多功能。是否可以在不使用向量和动态内存的情况下使其以相同的方式运行?以上是关于将文本文件 C++ 从特定行解析到特定行的主要内容,如果未能解决你的问题,请参考以下文章