解析文本文档并在 C++ 中打印

Parsing text document and print in c++

本文关键字:C++ 打印 文本 文档      更新时间:2023-10-16

我想解析我的文本文件并仅打印指定的数据。在我的文档中,我从行日期时间终端到行搜索数据,请联系您的办公室并打印。但是现在我想自定义我的输出并收集所有客户的所有笔记(总笔记 = 1,2 美元,10 美元,20 美元,1,3 美元..= 1+2+10+20+1+3+5+10(,总笔记 = 52。输出看起来像

OUTPUT File: 
Total notes: 52
==============================
1.  Client: 123456******3381
DATE: 13.03.2019 TIME: 11:50 
1 х 50 USD
2 х 100 USD
2.  Client: 123456******3381
Date: 13.03.2019 Time: 12:23 
5 х 10 USD
10 x 20 USD
2.  Client: 123456******3381
Date: 13.03.2019 Time: 08:45 
1 х 10 USD
3 x 20 USD
5 x 50 USD
10 x 100 USD
==============================

....
....
        while (getline(input, line))
        {  
            //count++;
            pos = line.find("DATA/DATE");
            pos2 = line.find("PLEASE CONTACT YOUR OFFICE");
            card = line.find("ID:");
            char arr[] = "ID:";
            found = line.find(arr, found + 1);
            //if (found != string::npos)
                if (pos != string::npos) // string::npos is returned if string is not found
                {

                          outFile.open("outfile.txt", std::ofstream::out | std::ofstream::app);
                          outFile << count << ". Client: n" << endl;
                          outFile << "DATA/DATE      TIME     TERMINAL" << endl;
                          while (getline(input, line))
                          {

                                   cout << line << endl;
                                  outFile << line << endl;
                                    string::size_type middle_begin = line.find(" USD") + 1;
                                    string::size_type middle_end = line.find("n", middle_begin);
                                    string middle = line.substr(middle_begin, middle_end - middle_begin);
                                    cout  << middle << endl;
                                    int c;
                                    c = atoi(middle.c_str());
                                    cout << c << endl;
                                  if (line == "PLEASE CONTACT YOUR OFFICE") {
                                      outFile << "----------------------------------------" << endl;
                                      outFile << "n" << endl;
                                      count++;
                                      goto BEGIN;
                                  }
                          }

                }
outFile.close();
        }
    }
    system("notepad /p outfile.txt");

}
My output:
1. Client: 
DATA/DATE      TIME     TERMINAL
2019.07.16     20:07:27     TID00302 
----------------------------------------
ID: 123456******3381
AID: A0000000043060
**************************************
PLEASE KEEP THIS RECEIPT
AND CONTACT YOUR OFFICE
**************************************
NOTES:
50  USD 1                     
100  USD 2             
PLEASE CONTACT YOUR OFFICE
----------------------------------------

2. Client: 
DATA/DATE      TIME     TERMINAL
2019.07.16     20:07:27     TID00302 
----------------------------------------
CARD: 123456******3381
AID: A0000000043060
**************************************
PLEASE KEEP THIS RECEIPT
AND CONTACT YOUR OFFICE
**************************************
NOTES:
5  USD 10                     
10  USD 20            
PLEASE CONTACT YOUR OFFICE
----------------------------------------

3. Client: 
DATA/DATE      TIME     TERMINAL
2019.07.16     20:07:27     TID00302 
----------------------------------------
ID: 123456******3381
AID: A0000000043060
**************************************
PLEASE KEEP THIS RECEIPT
AND CONTACT YOUR OFFICE
**************************************
NOTES:
10  USD 1                     
20  USD 3 
50  USD 5  
100 USD 10          
PLEASE CONTACT YOUR OFFICE
----------------------------------------
INPUT FILE:
....
Some other text
APPROVAL CODE:1264
Decline reason message:  Common decline
=================================================
10:22:23 INFORMATION REQUEST AB    C 
10:22:24 INFORMATION REPLY NEXT  FUNCTION 5
10:22:32 INFORMATION REQUEST AA      
10:22:32 INFORMATION REPLY NEXT 0 FUNCTION 100
10:22:35 INFORMATION REQUEST AC 
10:22:36 INFORMATION REPLY NEXT 016 FUNCTION 
10:22:45 INFORMATION REQUEST B DA 
10:22:45 INFORMATION REPLY NEXT 021 
10:22:52 INFORMATION REQUEST  A AA CB
10:22:53 INFORMATION REPLY NEXT 104 FUNCTION 2047
================ INFO ================
2018.07.18 10:23:41  - 4784
IDCR: 1111520
SOLUTION: A:5 B:5 C:5
=================================================
DATA/DATE      TIME     TERMINAL
2019.07.16     20:07:27     TID00302 
----------------------------------------
ID: 123456******3381
AID: A0000000043060
**************************************
PLEASE KEEP THIS RECEIPT
AND CONTACT YOUR OFFICE
**************************************
NOTES:
50  USD 1                     
100  USD 2             
PLEASE CONTACT YOUR OFFICE
----------------------------------------
10:23:09 INFORMATION REQUEST AB
10:23:09 INFORMATION REPLY NEXT 010 FUNCTION 5000
10:39:42 INFORMATION REQUEST AA      
10:39:42 INFORMATION REPLY NEXT 500 FUNCTION 5000
10:39:48 INFORMATION REQUEST AC A  B 
10:39:49 INFORMATION REPLY NEXT 016 FUNCTION 5000
10:39:51 INFORMATION REQUEST B DAA B 
10:39:51 INFORMATION REPLY NEXT 021 FUNCTION 5000
10:40:04 INFORMATION REQUEST  A AA BB
10:40:04 INFORMATION REPLY NEXT 620 FUNCTION 5000
10:40:06 INFORMATION REQUEST    ACCBB
================ INFO ================
2018.07.18 10:40:41  - 1235
IDCR: 1111220
SOLUTION: A:5 B:5 C:5
=================================================
10:22:23 INFORMATION REQUEST AB    C 
10:22:24 INFORMATION REPLY NEXT  FUNCTION 5
10:22:32 INFORMATION REQUEST AA      
10:22:32 INFORMATION REPLY NEXT 0 FUNCTION 100
10:22:35 INFORMATION REQUEST AC 
10:22:36 INFORMATION REPLY NEXT 016 FUNCTION 
10:22:45 INFORMATION REQUEST B DA 
10:22:45 INFORMATION REPLY NEXT 021 
10:22:52 INFORMATION REQUEST  A AA CB
10:22:53 INFORMATION REPLY NEXT 104 FUNCTION 2047
DATA/DATE      TIME     TERMINAL
2019.07.16     20:07:27     TID00302 
----------------------------------------
CARD: 123456******3381
AID: A0000000043060
**************************************
PLEASE KEEP THIS RECEIPT
AND CONTACT YOUR OFFICE
**************************************
NOTES:
5  USD 10                     
10  USD 20            
PLEASE CONTACT YOUR OFFICE
----------------------------------------
APPROVAL CODE:
Decline reason message:  Common decline
=================================================
10:22:23 INFORMATION REQUEST AB    C 
10:22:24 INFORMATION REPLY NEXT  FUNCTION 5
10:22:32 INFORMATION REQUEST AA      
10:22:32 INFORMATION REPLY NEXT 0 FUNCTION 100
10:22:35 INFORMATION REQUEST AC 
10:22:36 INFORMATION REPLY NEXT 016 FUNCTION 
10:22:45 INFORMATION REQUEST B DA 
10:22:45 INFORMATION REPLY NEXT 021 
10:22:52 INFORMATION REQUEST  A AA CB
10:22:53 INFORMATION REPLY NEXT 104 FUNCTION 2047
APPROVAL CODE:
Decline reason message:  Common decline
=================================================
10:22:23 INFORMATION REQUEST AB    C 
10:22:24 INFORMATION REPLY NEXT  FUNCTION 5
10:22:32 INFORMATION REQUEST AA      
10:22:32 INFORMATION REPLY NEXT 0 FUNCTION 100
10:22:35 INFORMATION REQUEST AC 
10:22:36 INFORMATION REPLY NEXT 016 FUNCTION 
10:22:45 INFORMATION REQUEST B DA 
10:22:45 INFORMATION REPLY NEXT 021 
10:22:52 INFORMATION REQUEST  A AA CB
10:22:53 INFORMATION REPLY NEXT 104 FUNCTION 2047
DATA/DATE      TIME     TERMINAL
2019.07.16     20:07:27     TID00302 
----------------------------------------
ID: 123456******3381
AID: A0000000043060
**************************************
PLEASE KEEP THIS RECEIPT
AND CONTACT YOUR OFFICE
**************************************
NOTES:
10  USD 1                     
20  USD 3 
50  USD 5  
100 USD 10          
PLEASE CONTACT YOUR OFFICE
----------------------------------------
APPROVAL CODE:
Decline reason message:  Common decline
=================================================
10:22:23 INFORMATION REQUEST AB    C 
10:22:24 INFORMATION REPLY NEXT  FUNCTION 5
10:22:32 INFORMATION REQUEST AA      
10:22:32 INFORMATION REPLY NEXT 0 FUNCTION 100
10:22:35 INFORMATION REQUEST AC 
10:22:36 INFORMATION REPLY NEXT 016 FUNCTION 
10:22:45 INFORMATION REQUEST B DA 
10:22:45 INFORMATION REPLY NEXT 021 
10:22:52 INFORMATION REQUEST  A AA CB
10:22:53 INFORMATION REPLY NEXT 104 FUNCTION 2047

Lts 看到一个完整的代码示例,可以很好地解决您的问题。上市后,我会解释一点

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <fstream>
#include <iterator>
#include <numeric>
#include <algorithm>
struct ClientData
{
    // The clients data. Everything stored as string
    std::string id{};
    std::string date{};
    std::string time{};
    // The notes will bes trored in a map. Key is not type and value is note count
    std::map<unsigned int, unsigned int> notes{};
    // Get the overall number of notes for thiy record
    size_t getNumberOfNotes() const { size_t sum{ 0 }; for (auto const& [k, v] : notes) sum += v; return sum; }
    // Read and parse parts of the input file
    friend std::istream& operator >> (std::istream& is, ClientData& cd);
    // Out put function. Print data in required format
    friend std::ostream& operator << (std::ostream& os, ClientData& cd) {
        os << "   Client: " << cd.id << "nDATE: " << cd.date << " Time: " << cd.time;;
        for (auto const& [k, v] : cd.notes) os << 'n' << v << " x " << k << " USD";
        return os;
    }
};
// The inserter operator. Parse the input using a sate machine
std::istream& operator >> (std::istream& is, ClientData& cd)
{
    // States for our state machine
    enum class States { WaitForDate, ReadDate, WaitForID, WaitForNotes1, WaitForNotes2, ReadNotes};
    // Initially or note map is empty
    cd.notes.clear();
    // Loop conditions
    bool tryToRead{ true }; bool failureDuringRead{ false };
    // Initial state
    States state{ States::WaitForDate };
    // Read all line belonging to this record
    while (tryToRead && !failureDuringRead) {
        std::string line{};
        if (std::getline(is, line)) {
            // State machine to always do the appropiate operation
            switch (state)
            {
            case States::WaitForDate:    // Wait for the line 
                if (line == "DATA/DATE      TIME     TERMINAL") 
                    state = States::ReadDate;  // If found, goto next state
                break;
            case States::ReadDate: 
                {
                    // extract the date and the time
                    std::istringstream iss(line);
                    iss >> cd.date >> cd.time;
                }  
                state = States::WaitForID; // Next:: Wait for the ID string
                break;
            case States::WaitForID:
                // We are waiting for the ID string. Denominated with "ID" or "CARD"
                if ((line.find("CARD:") == 0) || (line.find("ID:") == 0))
                {
                    // Found, extract is string
                    std::string idOrCard{}; // Dummy. Will not be used
                    std::istringstream iss(line);
                    iss >> idOrCard  >> cd.id;
                    state = States::WaitForNotes1; // Next: wait for "Notes" String
                }
                break;
            case States::WaitForNotes1:
                if (line.find("NOTES:") == 0)    // If we can find the NOTES string
                    state = States::WaitForNotes2;  // Then Next: Read the empty line after "NOTES:"
                break;
            case States::WaitForNotes2:
                // Read empty line
                state = States::ReadNotes;
                break;
            case States::ReadNotes:
                // now read the notes. As long as there is data avaliable (and no empty line)
                if (line != "") {
                    std::string usd{}; // Dummy. Will not be used
                    std::istringstream iss(line);
                    // Extract notes
                    unsigned int type{}; unsigned int count{};
                    iss >> type >> usd >> count;
                    // And put it in map
                    cd.notes[type] += count;
                }
                else {
                    // Empty line found. Done with this record. Everything read.
                    tryToRead = false;             // Stop reading lines
                    state = States::WaitForDate;   // Wait for Date again
                }
                break;
            default:
                std::cerr << "Invalid Staten";
                failureDuringRead = true;
                tryToRead = false;
            }
        }
        else {
            // Error while reading
            cd.id.clear(); cd.date.clear(); cd.time.clear(); cd.notes.clear();
            tryToRead = false;
        }
    }
    return is;
}
int main()
{
    // Open input file
    std::ifstream ifs("r:\input.txt");
    if (ifs) {
        // Read and parse all records with one statement
        std::vector<ClientData> clientData{std::istream_iterator<ClientData>(ifs),std::istream_iterator<ClientData>() };
        // Get total sum of notes
        size_t totalSumOfNotes{ 0 };
        for (const ClientData& cd : clientData) totalSumOfNotes += cd.getNumberOfNotes();
        // Print result in requested format. You can of course replace std::cout by any ofstream
        std::cout << "Total notes: " << totalSumOfNotes << "n===============================";
        for (size_t i = 0; i < clientData.size(); ++i)  {
            std::cout << 'n' << (i + 1) << ".  " << clientData[i] << 'n';
        }
        std::cout << "===============================n";
    }
    else
        std::cerr << "Could not open imput filen";
    return 0;
}

我们使用面向对象的方法,并将属于一个类的所有数据放在一起。然后我们将定义成员函数。这里尤其是提取器操作员。

在这里,我们使用状态机。状态机处于当前状态,等待某些事情发生。如果满足条件,则执行操作,我们将进入下一个状态。调味品始终是我们搜索的字符串。这些操作完成工作并收集数据。

非常简单。请尝试阅读和理解。如果您还有其他问题,请询问。