C++ 将std::string解析为坐标?
我有一个这样的字符串(都是正整数,方括号中没有空格): 我想这样提取int:1,2,10,4,5,12。 我现在使用的代码不处理int>=10C++ 将std::string解析为坐标?,c++,string,parsing,C++,String,Parsing,我有一个这样的字符串(都是正整数,方括号中没有空格): 我想这样提取int:1,2,10,4,5,12。 我现在使用的代码不处理int>=10 std::istringstream coor(coorstring); std::vector<int> num; char c; while (coor.get(c)){ if (isdigit(c)){ unsigned int a = c - '0'; if (a<
std::istringstream coor(coorstring);
std::vector<int> num;
char c;
while (coor.get(c)){
if (isdigit(c)){
unsigned int a = c - '0';
if (a<max) {num.push_back(a);}
}
}
std::istringstream coor(coorstring);
std::向量数;
字符c;
while(coor.get(c)){
if(isdigit(c)){
无符号整数a=c-'0';
如果(a仅使用字符串拆分:
std::string s = "[(1,2),(10,4),(5,12),... ]";
std::string delimiter = ",";
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
// deal with the data here
s.erase(0, pos + delimiter.length());
}
它应该输出相当规则的数据,所有这些数据的格式您都知道:
"[(1", "2)", "(10", "4)", etc...
您可以使用std::ignore(1000'(')
跳过所有内容,直到(包括)下一个圆括号,然后使用运算符>
读取第一个坐标、逗号和第二个坐标
此外,我建议使用数据结构pair
来表示一对坐标:
int main() {
std::istringstream coor("[(1,2),(10,4),(5,12),... ]");
std::vector<pair<int,int>> coordinates;
for(;;) {
coor.ignore(std::numeric_limits<std::streamsize>::max(), '(');
int x,y;
char c;
if (!(coor >> x >> c >> y)) {
break;
}
coordinates.push_back(pair<int,int>(x,y));
}
for (auto coordinate : coordinates) {
cout << coordinate.first << "/" << coordinate.second << endl;
}
}
intmain(){
标准::istringstream coor(“[(1,2),(10,4),(5,12),…]”;
向量坐标;
对于(;;){
忽略(std::numeric_limits::max(),'(');
int x,y;
字符c;
如果(!(coor>>x>>c>>y)){
打破
}
坐标。推回(对(x,y));
}
用于(自动坐标:坐标){
cout不完全是解决方案,但此时您应该听到:
除了已经存在的工具和功能外,当你遇到任何问题时,从以下几点开始:你自己是如何做到的?你在脑海中经过哪些步骤,从纸上的一些符号到诸如点之类的概念?如果你遇到一个完全不知道如何阅读的人,你会如何向他解释
此外,考虑子问题。也许可以开始考虑一种方法,将(8,1)之类的东西转换为一个点,然后将它们连接起来。不要害怕编写几十个将一个东西转换为另一个东西的独立函数。使用不存在的函数,然后编写它们。以下是一些代码,可能有助于您学习:
struct Point;
void remove_symbol(string& input, const char symbol);
Point parse_point(const string& input); //"(8,1)" -> Point on that coordinates
vector<string> delimit_by(const string& input, const char delimiter);
struct点;
无效删除_符号(字符串和输入,常量字符符号);
点解析_点(常量字符串和输入);/“(8,1)”->该坐标上的点
向量分隔符(常量字符串和输入,常量字符分隔符);
没有故意提供实现-尝试编写所有实现,然后再次询问是否有效。一些基本提示,即使这可能不是最优雅的代码:您可以通过string::length()
和[]-运算符与数组一样迭代整数的内容,还可以通过+=(不合法,因为成本高昂,但一开始就很容易)
(使用STL可能总是有直接的方法来做这些事情,但是一开始自己编写它们会给你一些经验,而且你不可能知道所有的STL。只要确保从长远来看了解更多关于STL的知识。)简单的双通算法,生成std::vector/point
s:
std::string s = "[(1,2),(10,4),(5,12),... ]";
std::replace_if( s.begin(), s.end(), []( char c ) { return !std::isdigit( c ); }, ' ' );
std::istringstream ss( s );
int x, y;
while (ss >> x >> y)
points.emplace_back( point( x, y ) );
您可以任意方式声明点
,例如:
struct point
{
int x, y;
point(): x(), y() { }
point( int x, int y ): x(x), y(y) { }
};
*取决于stringstream构造函数,该构造函数可能会执行另一个过程。此算法执行显式两个过程。我将定义一些自定义的运算符>
提取运算符来处理此问题:
typedef std::pair<int, int> point;
typedef std::vector<point> points;
std::istream& operator>>(std::istream &in, point &out)
{
char ch1, ch2, ch3;
if (in >> ch1 >> out.first >> ch2 >> out.second >> ch3)
{
if ((ch1 != '(') || (ch2 != ',') || (ch3 != ')'))
in.setstate(std::ios_base::failbit);
}
return in;
}
std::istream& operator>>(std::istream &in, points &out)
{
point pt;
char ch;
if (!(in >> ch))
return in;
if (ch != '[')
{
in.setstate(std::ios_base::failbit);
return in;
}
ch = in.peek();
do
{
if (ch == std::istream::traits_type::eof())
{
in.setstate(std::ios_base::failbit);
break;
}
if (ch == ']')
{
in.ignore(1);
break;
}
if (ch != '(')
{
in.setstate(std::ios_base::failbit);
break;
}
if (!(in >> pt))
break;
out.push_back(pt);
ch = in.peek();
if (ch == ',')
{
in.ignore(1);
ch = in.peek();
}
}
while (true);
return in;
}
为了阅读“10”,你需要阅读和处理不止一个字符。因此,基本上你是在问“如何编写解析器”-对吗?这是一个已解决的问题(假设你可以构造一个合适的语法)。互联网拥有所有需要的信息-一个起点可能是。还可以查找“lexer”和“tokenizer”等关键字。您是否考虑过将字符串拆分为(x,y)
部分,然后将其拆分为x
/y
?这将是第一个想到的想法。最大值超过-!这将使您更容易删除“[”和“]'字符。第二种解决方案是删除所有不是数字或逗号的字符。然后,用逗号分隔符拆分字符串。(这可能更容易)Thx!很好的建议!我发现了一个如下的擦除函数:
typedef std::pair<int, int> point;
typedef std::vector<point> points;
std::istream& operator>>(std::istream &in, point &out)
{
char ch1, ch2, ch3;
if (in >> ch1 >> out.first >> ch2 >> out.second >> ch3)
{
if ((ch1 != '(') || (ch2 != ',') || (ch3 != ')'))
in.setstate(std::ios_base::failbit);
}
return in;
}
std::istream& operator>>(std::istream &in, points &out)
{
point pt;
char ch;
if (!(in >> ch))
return in;
if (ch != '[')
{
in.setstate(std::ios_base::failbit);
return in;
}
ch = in.peek();
do
{
if (ch == std::istream::traits_type::eof())
{
in.setstate(std::ios_base::failbit);
break;
}
if (ch == ']')
{
in.ignore(1);
break;
}
if (ch != '(')
{
in.setstate(std::ios_base::failbit);
break;
}
if (!(in >> pt))
break;
out.push_back(pt);
ch = in.peek();
if (ch == ',')
{
in.ignore(1);
ch = in.peek();
}
}
while (true);
return in;
}
std::istringstream iss(coorstring);
points coords;
iss >> coords;