2016-10-03 3 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; 

С помощью этого файла, я получил это error: Ошибка C2679 двоичная '>>': оператор не найден, который принимает правый операнд ty «Const символ [2]» ре (или нет приемлемой конверсии)

ответ

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<<, вместо этого эти два символа изменены, чтобы вместо этого получить 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 и г ++ 6.1 (но это не раздвигает границы компиляторов на всех, так что я бы ожидать, что она отлично работает даже с такими старыми компиляторами они ужасно разбиты вообще (например, gcc 2.x или VC++ 6.0).

+0

Привет, Джерри. Это именно то, что я искал. Кроме того, я не могу найти документацию об этом Я имею в виду, какой технический термин использовать, если я хочу найти некоторую информацию о iostream >> (char *) что-то? Большое спасибо за все детали! – Aesope

+0

@Aesope: Я не знаю, что есть много деталей, кроме того, что это просто еще одна перегрузка оператора. Существует существующая перегрузка для чтения строки в (указатель, на который ссылается) указатель. Это просто еще одна перегрузка, основанная на 'const'ness указателя. Перегрузка на константу должна быть покрыта любой достойной книгой на C++; это еще одно применение хорошо известной возможности. –

+0

Привет, Джерри. Это то, что я думал. Между тем у меня возникла странная ошибка при компиляции. Нужен ли мне специальный файл заголовка? или что-то другое? Я получил эту компиляционную ошибку от MSVC++ 2015: ошибка C2679: двоичный '>>': оператор не найден, который принимает правый операнд типа 'const char [2]' (или нет приемлемого преобразования) – Aesope

Смежные вопросы