C++ 带格式化字符串的istream提取值

C++ 带格式化字符串的istream提取值,c++,text,formatting,iostream,istream,C++,Text,Formatting,Iostream,Istream,我在一个istream中有这个格式化字符串 (5,-4) 比如说: 开括号 整数 逗号和空格 另一个整数 右括号 我想知道提取整数和验证字符串格式的最佳方法是什么 这是在这样一个类中: class MyPoint { public: MyPoint() = default; ~MyPoint() = default; ... friend ostream & operator>>(ostream & lhs, MyPoint const &am

我在一个istream中有这个格式化字符串

(5,-4)

比如说:

  • 开括号
  • 整数
  • 逗号和空格
  • 另一个整数
  • 右括号
  • 我想知道提取整数和验证字符串格式的最佳方法是什么

    这是在这样一个类中:

    class MyPoint
    {
    public:
       MyPoint() = default;
       ~MyPoint() = default;
       ...
       friend ostream & operator>>(ostream & lhs, MyPoint const & rhs);
       ...
    private:
       int x, y;
    };
    
    ostream & operator>>(ostream & lhs, MyPoint const & rhs) {
        // ???
    }
    
    非常感谢大家

    这是我的头文件

    #ifndef MYPOINT_H
    #define MYPOINT_H
    
    #include <iostream>
    using namespace std;
    
    class MyPoint
    {
    public:
        MyPoint() : mX{ 0 }, mY{ 0 } { ; }
        MyPoint(int x, int y) : mX{ x }, mY{ y } { ; }
        ~MyPoint() = default;
    
        int x() const { return mX; }
        int y() const { return mY; }
        void setX(int x) { mX = x; }
        void setY(int y) { mY = y; }
    
        MyPoint operator-() const { return MyPoint(-mX, mY); }
        MyPoint operator+(MyPoint rhs) const { rhs.mX += mX; rhs.mY += mY; return rhs; }
        MyPoint operator-(MyPoint rhs) const { rhs.mX = mX - rhs.mX; rhs.mY = mY - rhs.mY; return rhs; }
        MyPoint operator*(MyPoint rhs) const { rhs.mX *= mX; rhs.mY *= mY; return rhs; }
        MyPoint operator/(MyPoint rhs) const { rhs.mX = mX / rhs.mX; rhs.mY = mY / rhs.mY; return rhs; }
        MyPoint operator%(MyPoint rhs) const { rhs.mX = mX % rhs.mX; rhs.mY = mY % rhs.mY; return rhs; }
    
        friend MyPoint operator+(int lhs, MyPoint const & rhs);
        friend MyPoint operator-(int lhs, MyPoint const & rhs);
        friend MyPoint operator*(int lhs, MyPoint const & rhs);
        friend MyPoint operator/(int lhs, MyPoint const & rhs);
        friend MyPoint operator%(int lhs, MyPoint const & rhs);
    
        friend ostream & operator<<(ostream & lhs, MyPoint const & rhs);
        friend istream & operator>>(istream & lhs, MyPoint & rhs);
    
    private:
        int mX, mY;
    
    };
    
    #endif //MYPOINT_H
    
    \ifndef MYPOINT\u H
    #定义MYPOINT_H
    #包括
    使用名称空间std;
    类MyPoint
    {
    公众:
    MyPoint():mX{0},mY{0}{;}
    MyPoint(intx,inty):mX{x},mY{y}{;}
    ~MyPoint()=默认值;
    int x()常量{return mX;}
    int y()常量{return mY;}
    void setX(int x){mX=x;}
    void setY(int y){mY=y;}
    MyPoint操作符-()常量{return MyPoint(-mX,mY);}
    MyPoint运算符+(MyPoint rhs)常量{rhs.mX+=mX;rhs.mY+=mY;返回rhs;}
    MyPoint操作符-(MyPoint rhs)const{rhs.mX=mX-rhs.mX;rhs.mY=mY-rhs.mY;返回rhs;}
    MyPoint运算符*(MyPoint rhs)常量{rhs.mX*=mX;rhs.mY*=mY;返回rhs;}
    MyPoint操作符/(MyPoint rhs)常量{rhs.mX=mX/rhs.mX;rhs.mY=mY/rhs.mY;返回rhs;}
    MyPoint运算符%(MyPoint rhs)常量{rhs.mX=mX%rhs.mX;rhs.mY=mY%rhs.mY;返回rhs;}
    友元MyPoint运算符+(int-lhs、MyPoint常量和rhs);
    友元MyPoint操作符-(int-lhs、MyPoint-const和rhs);
    友元MyPoint操作符*(int-lhs、MyPoint-const和rhs);
    友元MyPoint操作符/(int-lhs、MyPoint-const和rhs);
    友元MyPoint运算符%(内部左侧、MyPoint常量和右侧);
    friend ostream&operator(istream&lhs、MyPoint&rhs);
    私人:
    intmx,我的;
    };
    #endif//MYPOINT\u H
    
    这是我的源文件

    #include "MyPoint.h"
    
    
    MyPoint operator+(int lhs, MyPoint const & rhs) {
        return MyPoint(lhs + rhs.mX, lhs + rhs.mY);
    }
    MyPoint operator-(int lhs, MyPoint const & rhs) {
        return MyPoint(lhs - rhs.mX, lhs - rhs.mY);
    }
    MyPoint operator*(int lhs, MyPoint const & rhs) {
        return MyPoint(lhs * rhs.mX, lhs * rhs.mY);
    }
    MyPoint operator/(int lhs, MyPoint const & rhs) {
        return MyPoint(lhs / rhs.mX, lhs / rhs.mY);
    }
    MyPoint operator%(int lhs, MyPoint const & rhs) {
        return MyPoint(lhs % rhs.mX, lhs % rhs.mY);
    }
    
    ostream & operator<<(ostream & lhs, MyPoint const & rhs) {
        return lhs << "(" << rhs.mX << "," << rhs.mY << ")";
    }
    istream & operator >> (istream & lhs, MyPoint & rhs) {
        return lhs >> "(" >> rhs.mX >> "," >> rhs.mY >> ")"; // HERE is the compiling error
    }
    
    #包括“MyPoint.h”
    MyPoint运算符+(内部左侧、MyPoint常量和右侧){
    返回MyPoint(lhs+rhs.mX,lhs+rhs.mY);
    }
    MyPoint运算符-(内部左侧、MyPoint常量和右侧){
    返回MyPoint(lhs-rhs.mX,lhs-rhs.mY);
    }
    MyPoint运算符*(内部左侧、MyPoint常量和右侧){
    返回MyPoint(lhs*rhs.mX,lhs*rhs.mY);
    }
    MyPoint运算符/(内部左侧、MyPoint常量和右侧){
    返回MyPoint(lhs/rhs.mX,lhs/rhs.mY);
    }
    MyPoint运算符%(内部左侧、MyPoint常量和右侧){
    返回MyPoint(lhs%rhs.mX,lhs%rhs.mY);
    }
    ostream&运算符>“,”>>rhs.mY>>”;//下面是编译错误
    }
    
    最后,主要是测试

    MyPoint p1, p2(2, -2);
    cout << p1 << endl;
    cout << p2 << endl;
    
    mypointp1,p2(2,-2);
    
    cout对于这种情况,我经常发现定义
    操作符>>
    的重载以从流中读取预定义字符串非常方便:

    std::istream &operator>>(std::istream &is, char const *pat) {
    
        char ch;
        while (isspace(static_cast<unsigned char>(is.peek())))
            is.get(ch);
    
        while (*pat && is && *pat == is.peek() && is.get(ch)) {
            ++pat;
        }
    
        // if we didn't reach the end of the pattern, matching failed (mismatch, premature EOF, etc.)
        if (*pat) {
            is.setstate(std::ios::failbit);
        }
    
        return is;
    }
    
    这将像大多数典型的重载一样,并在给定的模式不匹配时设置流的失败位。现在,输入中的每个字符串前面都可以有任意的空格(就像数字等的转换一样)

    这里有一个技术上的小错误:目前,它使用全局语言环境的空白定义。要真正正确,它可能应该使用与输入流关联的区域设置中提供的定义

    还要注意,我必须更改您对
    操作符>>
    位的定义;在这个问题中,它看起来像是一个超负荷的
    操作符

    举个简单的例子:

    #include <iostream>
    
    std::istream &operator>>(std::istream &is, char const *pat) {
        // implementation above
    }
    
    class Point {
        int x, y;
    
        friend std::istream &operator>>(std::istream &is, Point &p) { 
            return is >> "(" >> p.x >>"," >> p.y >> ")";
        }
    
        friend std::ostream &operator<<(std::ostream &os, Point const &p) { 
            return os << "(" << p.x <<", " << p.y << ")";
        }
    };
    
    int main() {
        Point p;
    
        std::cout << "Please enter a point: ";
        std::cin >> p;
        std::cout << "Thanks. Point: " << p << '\n';
    }
    
    #包括
    std::istream&operator>>(std::istream&is,字符常量*pat){
    //上述实施
    }
    类点{
    int x,y;
    friend std::istream&operator>>(std::istream&is,Point&p){
    返回值为>>“(“>>p.x>>”,“>>p.y>>”);
    }
    
    friend std::ostream&operator对于这种情况,我经常发现定义
    operator>
    重载从流中读取预定义字符串非常方便:

    std::istream &operator>>(std::istream &is, char const *pat) {
    
        char ch;
        while (isspace(static_cast<unsigned char>(is.peek())))
            is.get(ch);
    
        while (*pat && is && *pat == is.peek() && is.get(ch)) {
            ++pat;
        }
    
        // if we didn't reach the end of the pattern, matching failed (mismatch, premature EOF, etc.)
        if (*pat) {
            is.setstate(std::ios::failbit);
        }
    
        return is;
    }
    
    这将像大多数典型的重载一样,并在给定的模式不匹配时设置流的失败位。现在,输入中的每个字符串前面都可以有任意空格(就像数字等的转换)

    这里有一个技术上的小错误:目前,它使用全局区域设置的空白定义。为了真正正确,它可能应该使用与输入流关联的区域设置中提供的定义

    还要注意,我必须更改您对
    操作符>>
    位的定义;在问题中,它看起来像是
    操作符的重载

    举个简单的例子:

    #include <iostream>
    
    std::istream &operator>>(std::istream &is, char const *pat) {
        // implementation above
    }
    
    class Point {
        int x, y;
    
        friend std::istream &operator>>(std::istream &is, Point &p) { 
            return is >> "(" >> p.x >>"," >> p.y >> ")";
        }
    
        friend std::ostream &operator<<(std::ostream &os, Point const &p) { 
            return os << "(" << p.x <<", " << p.y << ")";
        }
    };
    
    int main() {
        Point p;
    
        std::cout << "Please enter a point: ";
        std::cin >> p;
        std::cout << "Thanks. Point: " << p << '\n';
    }
    
    #包括
    std::istream&operator>>(std::istream&is,字符常量*pat){
    //上述实施
    }
    类点{
    int x,y;
    friend std::istream&operator>>(std::istream&is,Point&p){
    返回值为>>“(“>>p.x>>”,“>>p.y>>”);
    }
    
    friend std::ostream&operatorHi Jerry。这正是我要找的。而且,我也找不到任何关于这种技术的文档。我的意思是,如果我想找到一些有关iostream>>(char*)的信息,应该使用什么技术术语有什么吗?非常感谢所有的细节!@Aesope:我不知道除了这只是一个操作符的另一个重载之外还有很多细节。有一个现有的重载可以将字符串读入(所指的缓冲区)一个指针。这只是指针的一个额外的重写,它的指针应该在C++的任何一本体面的书中被覆盖。这只是一个众所周知的功能的一个应用。嗨,杰瑞。这就是我的想法。同时,编译时我遇到了一个奇怪的错误。我需要一个特殊的头文件吗?或者别的什么东西。其他?我从MSVC++2015中得到了这个编译错误:错误C2679:二进制'>>':没有找到接受类型为'const char[2]'的右操作数的运算符(或者没有可接受的转换)@Aesope:您必须包含至少声明
    std::istream
    (例如,
    )的内容这段代码已经用VC++2015测试过了…嗨,Jerry。这正是我要找的。而且,我不能