简体   繁体   English

将文本文件 C++ 从特定行解析到特定行

[英]Parsing a text file C++ from specific line to specific line

so, I`m new to c++.所以,我是 C++ 的新手。 My task is parse text file that look like:我的任务是解析如下所示的文本文件:

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%

And it continuous for few thousand lines.I need to find where it writes RE004%on% and start processing lines in this loop until it finds RE005%off% and do it over and over until it file ends.它连续几千行。我需要找到它在哪里写 RE004%on% 并开始处理这个循环中的行,直到它找到 RE005%off% 并一遍又一遍地重复直到文件结束。 I was trying to do it with line.find, but I am pretty sure it is wrong way to solve this problem我试图用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;
}

Unfortunately your description si very unclear.不幸的是,您的描述很不清楚。 Also by reading your code, I can really not understand, what you intent to do.另外通过阅读您的代码,我真的无法理解您的意图。 And you edited your text and changed description.您编辑了文本并更改了描述。 Not so easy for me对我来说没那么容易

But, I made an educated guess.但是,我做了一个有根据的猜测。 . . . .

I read all data between your given delimiters, validate the checksum and split the lines into tokens.我读取给定分隔符之间的所有数据,验证校验和并将行拆分为令牌。 Finally I store all the lines-with-Tokens in a vector.最后,我将所有带有标记的行存储在一个向量中。 Then I filter for a specific value and output a column.然后我过滤特定值并输出一列。

Please stude and try to understand.请学习并尝试理解。 It is not so complicated.它没有那么复杂。

Thank you谢谢

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM