Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将std::string解析为坐标?_C++_String_Parsing - Fatal编程技术网

C++ 将std::string解析为坐标?

C++ 将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<

我有一个这样的字符串(都是正整数,方括号中没有空格):

我想这样提取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<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;