带有格式化字符串的 istream 提取值
istream extraction values with formatted string
我在 istream 中有这个格式化的字符串。
(5, -4)
假设:
- 左括号
- 一个整数
- 逗号和space
- 另一个整数
- 右括号
我想知道提取两个整数并验证字符串格式的最佳方法是什么。
这是在 class 这样的:
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 二进制“>>”:未找到接受类型 'const char [2]' 的右手操作数的运算符(或没有可接受的转换)
对于这种情况,我经常发现定义 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 >> ")";
}
这将像大多数典型的重载一样执行操作,并在您提供的模式不匹配时设置流的失败位。就目前而言,输入中的每个字符串前面都可以有任意白色 space(就像数字等的转换一样)。
这里有一个技术上的小错误:就目前而言,它使用了全局区域设置的白色定义space。准确地说,它应该使用与输入流关联的语言环境中提供的定义。
另请注意,我必须更改您对 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 和 g++ 6.1 进行了测试(但这根本没有突破编译器的极限,所以我希望它能工作很好,即使编译器太老了,它们通常都被严重破坏了(例如,gcc 2.x 或 VC++ 6.0)。
我在 istream 中有这个格式化的字符串。
(5, -4)
假设:
- 左括号
- 一个整数
- 逗号和space
- 另一个整数
- 右括号
我想知道提取两个整数并验证字符串格式的最佳方法是什么。
这是在 class 这样的:
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 二进制“>>”:未找到接受类型 'const char [2]' 的右手操作数的运算符(或没有可接受的转换)
对于这种情况,我经常发现定义 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 >> ")";
}
这将像大多数典型的重载一样执行操作,并在您提供的模式不匹配时设置流的失败位。就目前而言,输入中的每个字符串前面都可以有任意白色 space(就像数字等的转换一样)。
这里有一个技术上的小错误:就目前而言,它使用了全局区域设置的白色定义space。准确地说,它应该使用与输入流关联的语言环境中提供的定义。
另请注意,我必须更改您对 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 和 g++ 6.1 进行了测试(但这根本没有突破编译器的极限,所以我希望它能工作很好,即使编译器太老了,它们通常都被严重破坏了(例如,gcc 2.x 或 VC++ 6.0)。