如何从 txt 文件 c++ 中提取括号之间的数字?
How can I extract numbers between a parenthesis from a txt file c++?
我的问题是:我的逻辑有问题。我已经检测到它何时有括号,但现在我需要找到数字并知道它们在 txt 文件中重复了多少次。这是我的 txt 文件:
(Visual basic)
(Llorente)
(Porto, 2008)
(Sommerville, 2010)
References
Visual Basic. (s.f.). Navarra.
Llorente, P.B. (s.f.). Fortran.
Porto, J.P. (2008)
Sommerville, I. (2010). Software Engineering. Unite Kingdom: Pearson.
结果应该是:year : 2008 - 2 times, year : 2010 - 2 times, etc.
PD:谢谢我很菜鸟。
#include <regex>
#include <iostream>
#include <fstream>
#include <map>
//33
int main()
{
std::ifstream readStream("references.txt");
std::map<int, int> cMap;
std::string input;
std::regex reg(R"(\([a-zA-Z\s]*,?\s*([0-9]+)\))");
std::regex inte("(\+|-)?[[:digit:]]+");
///333
while (std::getline(readStream, input)) {
std::match_results < std::string::const_iterator > m;
if ((std::regex_search(input, m, reg)) ) {
int year = std::stoi(m[1]);
auto value = cMap.find(year);
if (value != cMap.end()) {
cMap[value->first] = value->second + 1;
} else {
cMap[year] = 1;
}
}
}
//33
for (auto x : cMap) {
std::cout << "year " << x.first << " is - " << x.second << " times." << std::endl;
}
//3
return 0;
}
您可以使用std::regex_search
方法来匹配行。但请记住在文件顶部包含 #include <regex>
。
#include <regex>
#include <iostream>
#include <fstream>
#include <map>
int main()
{
std::ifstream readStream("path/to/your/Example.txt");
std::map<int, int> countMap; // Map containing (year, count) value pairs.
std::string in;
std::regex reg(R"(\([a-zA-Z\s]*,?\s*([0-9]+)\))"); // For the regex: \([a-zA-Z\s]*,?\s*([0-9]+)\)
while (std::getline(readStream, in)) {
std::match_results < std::string::const_iterator > m;
if (std::regex_search(in, m, reg)) { // If the current line matches our regex pattern.
int year = std::stoi(m[1]); // The second element of the array contains our string representing the year.
auto val = countMap.find(year);
if (val != countMap.end()) { // If the year is already in the countMap we want to increment it.
countMap[val->first] = val->second + 1;
} else {
countMap[year] = 1; // year doesn't exist in the countMap, it is the first time.
}
}
}
for (auto x : countMap) { // x is of type std::pair<int, int> which is our (year, count) value pair
std::cout << "year " << x.first << " is - " << x.second << " times." << std::endl;
}
return 0;
}
对于OP的任务,一个简单的循环就可以完成遍历字符串所有字符的工作。从而管理了两种状态:
open
... true
在 '('
之后和 ')'
之前,否则为 false
number
... true
当找到数字时 open
是 true
.
虽然 number
是 true
,但会收集并组合成一个 int
。如果在 number
为 true
时发现非数字,则这是数字的结尾并存储该值。
数字检查也可以在行尾完成。在这种特定情况下,这意味着语法错误,因为它意味着缺少右括号 ()
)。 (OP 没有说明如何处理这个问题。)
我的示例代码:
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
std::vector<int> parseLine(const std::string &text)
{
bool open = false, number = false;
std::vector<int> values; int value = 0;
for (char c : text) {
switch (c) {
case '(': open = true; break;
case ')': open = false;
default:
if (open && c >= '0' && c <= '9') {
number = true;
(value *= 10) += (c - '0'); // value = 10 * value + (c - '0')
} else if (number) {
values.push_back(value);
value = 0; number = false;
}
}
}
if (number) {
values.push_back(value);
std::cerr << "ERROR: Missing ')' at line end!\n";
}
return values;
}
const std::string text =
"(Visual basic)\n"
"(Llorente)\n"
"(Porto, 2008)\n"
"(Sommerville, 2010)\n"
"References\n"
"Visual Basic. (s.f.). Navarra.\n"
"Llorente, P.B. (s.f.). Fortran.\n"
"Porto, J.P. (2008)\n"
"Sommerville, I. (2010). Software Engineering. Unite Kingdom: Pearson.\n";
int main()
{
// open file
std::istringstream in(text);
// parse/process file line by line
std::map<int, int> histo;
for (std::string line; std::getline(in, line);) {
const std::vector<int> values = parseLine(line);
// count occurrences of values
for (int value : values) ++histo[value];
}
// report
std::cout << "Report:\n";
for (const std::pair<int, int> &entry : histo) {
std::cout << entry.first << ": " << entry.second << '\n';
}
// done
return 0;
}
输出:
Report:
2008: 2
2010: 2
我的问题是:我的逻辑有问题。我已经检测到它何时有括号,但现在我需要找到数字并知道它们在 txt 文件中重复了多少次。这是我的 txt 文件:
(Visual basic)
(Llorente)
(Porto, 2008)
(Sommerville, 2010)
References
Visual Basic. (s.f.). Navarra.
Llorente, P.B. (s.f.). Fortran.
Porto, J.P. (2008)
Sommerville, I. (2010). Software Engineering. Unite Kingdom: Pearson.
结果应该是:year : 2008 - 2 times, year : 2010 - 2 times, etc. PD:谢谢我很菜鸟。
#include <regex>
#include <iostream>
#include <fstream>
#include <map>
//33
int main()
{
std::ifstream readStream("references.txt");
std::map<int, int> cMap;
std::string input;
std::regex reg(R"(\([a-zA-Z\s]*,?\s*([0-9]+)\))");
std::regex inte("(\+|-)?[[:digit:]]+");
///333
while (std::getline(readStream, input)) {
std::match_results < std::string::const_iterator > m;
if ((std::regex_search(input, m, reg)) ) {
int year = std::stoi(m[1]);
auto value = cMap.find(year);
if (value != cMap.end()) {
cMap[value->first] = value->second + 1;
} else {
cMap[year] = 1;
}
}
}
//33
for (auto x : cMap) {
std::cout << "year " << x.first << " is - " << x.second << " times." << std::endl;
}
//3
return 0;
}
您可以使用std::regex_search
方法来匹配行。但请记住在文件顶部包含 #include <regex>
。
#include <regex>
#include <iostream>
#include <fstream>
#include <map>
int main()
{
std::ifstream readStream("path/to/your/Example.txt");
std::map<int, int> countMap; // Map containing (year, count) value pairs.
std::string in;
std::regex reg(R"(\([a-zA-Z\s]*,?\s*([0-9]+)\))"); // For the regex: \([a-zA-Z\s]*,?\s*([0-9]+)\)
while (std::getline(readStream, in)) {
std::match_results < std::string::const_iterator > m;
if (std::regex_search(in, m, reg)) { // If the current line matches our regex pattern.
int year = std::stoi(m[1]); // The second element of the array contains our string representing the year.
auto val = countMap.find(year);
if (val != countMap.end()) { // If the year is already in the countMap we want to increment it.
countMap[val->first] = val->second + 1;
} else {
countMap[year] = 1; // year doesn't exist in the countMap, it is the first time.
}
}
}
for (auto x : countMap) { // x is of type std::pair<int, int> which is our (year, count) value pair
std::cout << "year " << x.first << " is - " << x.second << " times." << std::endl;
}
return 0;
}
对于OP的任务,一个简单的循环就可以完成遍历字符串所有字符的工作。从而管理了两种状态:
open
...true
在'('
之后和')'
之前,否则为 falsenumber
...true
当找到数字时open
是true
.
虽然 number
是 true
,但会收集并组合成一个 int
。如果在 number
为 true
时发现非数字,则这是数字的结尾并存储该值。
数字检查也可以在行尾完成。在这种特定情况下,这意味着语法错误,因为它意味着缺少右括号 ()
)。 (OP 没有说明如何处理这个问题。)
我的示例代码:
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
std::vector<int> parseLine(const std::string &text)
{
bool open = false, number = false;
std::vector<int> values; int value = 0;
for (char c : text) {
switch (c) {
case '(': open = true; break;
case ')': open = false;
default:
if (open && c >= '0' && c <= '9') {
number = true;
(value *= 10) += (c - '0'); // value = 10 * value + (c - '0')
} else if (number) {
values.push_back(value);
value = 0; number = false;
}
}
}
if (number) {
values.push_back(value);
std::cerr << "ERROR: Missing ')' at line end!\n";
}
return values;
}
const std::string text =
"(Visual basic)\n"
"(Llorente)\n"
"(Porto, 2008)\n"
"(Sommerville, 2010)\n"
"References\n"
"Visual Basic. (s.f.). Navarra.\n"
"Llorente, P.B. (s.f.). Fortran.\n"
"Porto, J.P. (2008)\n"
"Sommerville, I. (2010). Software Engineering. Unite Kingdom: Pearson.\n";
int main()
{
// open file
std::istringstream in(text);
// parse/process file line by line
std::map<int, int> histo;
for (std::string line; std::getline(in, line);) {
const std::vector<int> values = parseLine(line);
// count occurrences of values
for (int value : values) ++histo[value];
}
// report
std::cout << "Report:\n";
for (const std::pair<int, int> &entry : histo) {
std::cout << entry.first << ": " << entry.second << '\n';
}
// done
return 0;
}
输出:
Report:
2008: 2
2010: 2