解析文本文档并在 C++ 中打印
Parsing text document and print in c++
我想解析我的文本文件并只打印指定的数据。在我的文档中,我搜索了从 DATE TIME TERMINAL 行到 PLEASE CONTACT YOUR OFFICE 行的数据并打印出来。但现在我想自定义我的输出并收集所有客户的所有笔记(总笔记 = 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
请参阅完整的代码示例,可以很好地解决您的问题。上市后稍微解释一下
#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 State\n";
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 file\n";
return 0;
}
我们使用面向对象的方法并将所有属于一起的数据放在 class 中。然后我们将定义成员函数。尤其是提取器运算符。
在此我们使用状态机。状态机处于当前状态并等待某事发生。如果满足条件,则执行操作,我们将进入下一个状态。条件总是我们搜索的字符串。这些操作完成工作并收集数据。
非常简单。请尝试阅读和理解。如果还有问题,再问。
我想解析我的文本文件并只打印指定的数据。在我的文档中,我搜索了从 DATE TIME TERMINAL 行到 PLEASE CONTACT YOUR OFFICE 行的数据并打印出来。但现在我想自定义我的输出并收集所有客户的所有笔记(总笔记 = 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
请参阅完整的代码示例,可以很好地解决您的问题。上市后稍微解释一下
#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 State\n";
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 file\n";
return 0;
}
我们使用面向对象的方法并将所有属于一起的数据放在 class 中。然后我们将定义成员函数。尤其是提取器运算符。
在此我们使用状态机。状态机处于当前状态并等待某事发生。如果满足条件,则执行操作,我们将进入下一个状态。条件总是我们搜索的字符串。这些操作完成工作并收集数据。
非常简单。请尝试阅读和理解。如果还有问题,再问。