I cant parse all text from .txt file But when I run my code, I don't get what I wanted :(
My code:
int main()
{
/* inside "logMsg.txt"
1/ [111]{1}(text line from 111);
2/ [222]{2}(text line from 222);
3/ [333]{3}(text line from 333);
*/
ifstream textfile("logMsg.txt");
string log_line;
string log_time;
string log_type;
string log_comment;
// Get line number
getline(textfile, log_line, '/');
// Get Time by unix
getline(textfile, log_time, '[');
getline(textfile, log_time, ']');
// Get type of the function
getline(textfile, log_type, '{');
getline(textfile, log_type, '}');
// Get comment from data_
getline(textfile, log_comment, '(');
getline(textfile, log_comment, ')');
cout << "Line Of the log: " << log_line << "\n";
cout << "Type of the log: " << log_type << "\n";
cout << "Time of the log: " << log_time << "\n";
cout << "Comment of the log :" << log_comment << "\n";
}
Console:
Line Of the log: 1
Type of the log: 1
Time of the log: 111
Comment of the log :text line from 111
I wanted the parser to read all the lines, but the result is completely different
I don't understand what I'm doing wrong, I trying to get the following result:
Line Of the log: 1, 2, 3,
Type of the log: 1, 2, 3,
Time of the log: 111, 222, 333,
Comment of the log: text line from 111, text line from 222, text line from 333,
plz help :(
CodePudding user response:
I would recommend using regular expressions for this:
- The example below just parses each line using a given pattern. You may need to modify it, for instance, allowing whitespaces around certain fields.
#include <fmt/core.h>
#include <iostream> // cout
#include <regex>
#include <sstream> // istringstream
#include <string> // getline
int main() {
const std::string input{"1/ [111]{1}(text line from 111);\n2/ [222]{2}(text line from 222);\n3/ [333]{3}(text line from 333);"};
std::istringstream iss{input};
std::string line{};
while (std::getline(iss, line))
{
const std::regex pattern{R"(([\d ])/\s*\[(\d )\]\{(\d )\}\(([^)] )\);)"};
std::smatch matches{};
if (std::regex_match(line, matches, pattern))
{
std::cout << fmt::format ("Line: {}, type: {}, time: {}, comment: {}\n",
matches[1].str(), matches[2].str(), matches[3].str(), matches[4].str());
}
}
}
// Outputs:
//
// Line: 1, type: 111, time: 1, comment: text line from 111
// Line: 2, type: 222, time: 2, comment: text line from 222
// Line: 3, type: 333, time: 3, comment: text line from 333
- Should you want a different output (e.g. as it seems you suggest in your question, print all the line numbers, then all the times, and so on), you may want to use
std::vectorsfor keeping that information, and printing it at the end.
#include <algorithm> // copy
#include <iostream> // cout
#include <iterator> // ostream_iterator
#include <regex>
#include <sstream> // istringstream
#include <string> // getline
int main() {
const std::string input{"1/ [111]{1}(text line from 111);\n2/ [222]{2}(text line from 222);\n3/ [333]{3}(text line from 333);"};
std::istringstream iss{input};
std::vector<std::string> numbers{};
std::vector<std::string> types{};
std::vector<std::string> times{};
std::vector<std::string> comments{};
std::string line{};
while (std::getline(iss, line))
{
const std::regex pattern{R"(([\d ])/\s*\[(\d )\]\{(\d )\}\(([^)] )\);)"};
std::smatch matches{};
if (std::regex_match(line, matches, pattern))
{
numbers.push_back(matches[1]);
types.push_back(matches[2]);
times.push_back(matches[3]);
comments.push_back(matches[4]);
}
}
std::cout << "Line of the log: ";
std::copy(numbers.cbegin(), numbers.cend(), std::ostream_iterator<std::string>(std::cout, ", "));
std::cout << "\n";
std::cout << "Type of the log: ";
std::copy(types.cbegin(), types.cend(), std::ostream_iterator<std::string>(std::cout, ", "));
std::cout << "\n";
std::cout << "Time of the log: ";
std::copy(times.cbegin(), times.cend(), std::ostream_iterator<std::string>(std::cout, ", "));
std::cout << "\n";
std::cout << "Comment of the log: ";
std::copy(comments.cbegin(), comments.cend(), std::ostream_iterator<std::string>(std::cout, ", "));
std::cout << "\n";
}
// Outputs:
//
// Line of the log: 1, 2, 3,
// Type of the log: 111, 222, 333,
// Time of the log: 1, 2, 3,
// Comment of the log: text line from 111, text line from 222, text line from 333,
- Although you'd better use a single
std::vectorofstructs, with proper types for the numbers, types and times. In this case, you would need to convert the strings frommatchesto thestruct'sints (you could do that withstd::stoi).
struct LineInfo
{
int number{};
int type{};
int time{};
std::string comment{};
};
std::vector<LineInfo> line_infos{};
