如何从作为模式给出的 std::string 中提取单词?
How to extract words from std::string given as a pattern?
考虑一下,我们有一个文本文件,其中逐行包含二维坐标:
( 123 , 356 )
( 33 , 3158 )
( 12 , 5 )
等等。
当我们逐行扫描这个文本文件时,提取 x 和 y 坐标的最佳方法是什么?
我的方法好像不太优雅。我在 std::string
中获取行,然后在 运行 循环中提取所需的点:
void find_coordinates(std::string str, int &x, int &y) {
int i = 2;
std::string temp;
while (i < str.length()) {
if (str[i] == ' ') {
++i;
continue;
}
else if (str[i] == ',') {
x = std::stoi(temp);
temp.clear();
}
else if (str[i] == ')') {
y = std::stoi(temp);
return;
}
else
temp += str[i];
++i;
}
}
std::ifstream f("file.txt");
while (getline(f, line)) {
int x, y;
find_coordinates(line, x, y);
}
有时最古老、最简单的解决方案是最好的解决方案:
void find_coordinates(const std::string& str, int& x, int& y)
{
if (sscanf(str.c_str(), "( %d , %d )", &x, &y) != 2)
throw std::runtime_error("Parsing failed");
}
(live demo)
不过,如果您的格式变得更加灵活,这种方法将会失败。
我会使用 Boost tokenizer class 进行这种解析。
#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int, char**)
{
string text = "( 123 , 356 )";
char_separator<char> sep("(), ");
tokenizer< char_separator<char> > tokens(text, sep);
BOOST_FOREACH (const string& t, tokens) {
cout << t << "." << endl;
}
}
运行 here
考虑一下,我们有一个文本文件,其中逐行包含二维坐标:
( 123 , 356 )
( 33 , 3158 )
( 12 , 5 )
等等。
当我们逐行扫描这个文本文件时,提取 x 和 y 坐标的最佳方法是什么?
我的方法好像不太优雅。我在 std::string
中获取行,然后在 运行 循环中提取所需的点:
void find_coordinates(std::string str, int &x, int &y) {
int i = 2;
std::string temp;
while (i < str.length()) {
if (str[i] == ' ') {
++i;
continue;
}
else if (str[i] == ',') {
x = std::stoi(temp);
temp.clear();
}
else if (str[i] == ')') {
y = std::stoi(temp);
return;
}
else
temp += str[i];
++i;
}
}
std::ifstream f("file.txt");
while (getline(f, line)) {
int x, y;
find_coordinates(line, x, y);
}
有时最古老、最简单的解决方案是最好的解决方案:
void find_coordinates(const std::string& str, int& x, int& y)
{
if (sscanf(str.c_str(), "( %d , %d )", &x, &y) != 2)
throw std::runtime_error("Parsing failed");
}
(live demo)
不过,如果您的格式变得更加灵活,这种方法将会失败。
我会使用 Boost tokenizer class 进行这种解析。
#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int, char**)
{
string text = "( 123 , 356 )";
char_separator<char> sep("(), ");
tokenizer< char_separator<char> > tokens(text, sep);
BOOST_FOREACH (const string& t, tokens) {
cout << t << "." << endl;
}
}
运行 here