2016-10-03 10 views
0

私はistreamでこのフォーマットされた文字列を持っています。フォーマットされた文字列を含むistream抽出値

(5、-4)

レッツは言う:

  1. オープン括弧
  2. 整数
  3. カンマ、スペース
  4. 別の整数
  5. 閉じ括弧

整数の両方を抽出し、文字列の書式を検証するための最良の方法は何ですか。

これは、このようなクラスである:すべての

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 

そして、ここに私のソースファイル

#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 p1, p2(2, -2); 
cout << p1 << endl; 
cout << p2 << endl; 

でのテストは、私はこれを持っていますエラー: エラーC2679バイナリ '>>':演算子が見つかりません。これはtyの右辺のオペランドをとります。このような状況のために「のconst char型[2]」、PE(あるいは全く許容可能な変換はありません)

答えて

3

、私は多くの場合、それは便利なストリームから事前に定義された文字列を読み取るために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; 
} 

、あなたのフォーマットの読み取りがこのようになります:

istream & operator>>(istream & lhs, MyPoint & rhs) { 
    return lhs >> "(" >> rhs.x >> "," >> rhs.y >> ")"; 
} 

これは、最も典型的な過負荷のように行うと、あなたが与えてくれたのパターンが一致しない場合は、ストリームのビットを失敗に設定します。現在のように、入力の各文字列の前に任意の空白を付けることができます(数値などの変換のように)。

技術的にはマイナーなバグがあります。現時点では、グローバルロケールの空白の定義が使用されています。本当に正しいためには、入力ストリームに関連付けられたロケールで提供されている定義を使用しているはずです。

また、operator>>ビットの定義を変更する必要があります。質問ではoperator<<のオーバーロードのように見えますが、その2文字だけがoperator>>に変更されています。

迅速たとえば

#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'; 
} 

VC++ 2013、VC++ 2015、およびg ++ 6.1でテスト済み(しかし、これは全くのコンパイラの限界に挑戦されていないので、私はそれが正常に動作することを期待したいですコンパイラが古くても、一般的にひどく壊れています(例えばgcc 2.xやVC++ 6.0)。

+0

こんにちはJerry。これはまさに私が探していたものです。 また、技術的なことですが、iostream >>(char *)に関する情報を見つけたい場合は、技術用語は何ですか? すべての詳細について多くの感謝! – Aesope

+0

@Aesope:これはオペレータのもう一つの過負荷であるという事実を超えて詳細がたくさんあることはわかりません。文字列を(ポインタが参照する)ポインタに読み込むための既存のオーバーロードがあります。これはポインタの 'const'nessに基づくもう一つのオーバーロードに過ぎません。定数のオーバーロードは、C++のまともな本でカバーする必要があります。これは、よく知られている機能のもう1つのアプリケーションに過ぎません。 –

+0

こんにちはジェリー。それは私が思ったものです。一方、私はコンパイル中に奇妙なエラーが発生しました。私は特別なヘッダーファイルが必要ですか?または、他の何か? MSVC++ 2015からこのコンパイルエラーが発生しました: エラーC2679:バイナリ '>>': 'const char [2]'型の右オペランドを取る演算子が見つかりません。または許容できる変換はありません – Aesope

関連する問題