用流读取复杂的结构
Reading complex structures with streams
考虑我有以下"一对浮点数"对象输入格式:(第一个变量,第二个变量)例如(1.0,15.6)。
读这种结构体的最好方法是什么?在C中,我会使用scanf("(%f, %f)", &var1, &var2) -很好,不是吗?(是的,我知道它不提供类型安全等)
但是我知道使用c++流只有一种方法:
float var1, var2;
char tmp;
cin >> tmp;
cin >> var1;
cin >> tmp;
cin >> var2;
cin >> tmp;
看起来很丑,它只是一对浮点数。那么,有没有一种优雅的方式来做到这一点呢?像
cin >> "(" >> var1 >> ", " >> var2 >> ")";
可能是Boost。精神是你能找到的最接近的东西。下面是一个如何使用它来达到你想要的效果的例子。
我会写一个输入操作符:
从@Seth Carnegie那里偷来FloatPair。
因此输入现在看起来正常:
FloatPair c;
std::cin >> c;
我想让它看起来像这样。
std::istream& operator>>(std::istream& stream, FloatPair& out)
{
return stream >> I('(') >> out.a >> I(',') >> out.b >> I(')');
}
然后我有一个像这样的忽略对象。
如果您愿意,可以简单地进行模板化。为了使代码更简单,我把我的代码命名为I
template<typename T>
struct ignore
{
T ignoreItem;
ignore(T const& x): ignoreItem(x) {}
};
template<typename T>
ignore<T> I(T const& x) { return ignore<T>(x);} // This is where I in the above code comes from.
则忽略的输入操作符>>如下所示:
std::istream& operator>>(std::istream& stream, ignore<T> const& test)
{
T next;
if ((stream >> next) && (test.ignoreItem != next)) // if the stream already failed
{ stream.setstate(std::ios::badbit); // then don't change anything
} // as it may confuse people
return stream;
}
string的专门化。处理操作符>>在string上只读取一个单词的事实。
注意:在scanf()中,一个空格匹配1个或多个空格。因此,如果输入字符串中有空格,则遵循相同的规则。
template<>
struct ignore<std::string>
{
std::vector<std::string> ignoreItemVector;
ignore(std::string const& x)
{
// Split the input into a list of words to ignore.
std::stringstream words(x);
std::copy(std::istream_iterator<std::string>(words),
std::istream_iterator<std::string>(words),
std::back_inserter(ignoreItemVector)
);
}
};
template<>
std::istream& operator>><std::string>(std::istream& stream, ignore<std::string> const& test)
{
// Specifically ignore each word.
foreach(std::string const& loop, test.ignoreItemVector)
{
std::string next;
if ((stream >> next) && (loop != next)) // if the stream already failed
{ stream.setstate(std::ios::badbit); // then don't change anything
} // as it may confuse people
}
return stream;
}
我要做的是创建一个类来表示一对浮点数:
class FloatPair {
public:
FloatPair() : a(), b() { }
float a, b;
};
和重载operator>>
来处理流:
istream& operator>>(istream& rhs, FloatPair& out) {
rhs.ignore(256, '(');
rhs >> out.a;
rhs.ignore(256, ' ');
rhs >> out.b;
rhs.ignore(256, ')');
return rhs;
}
所以你可以直接输入FloatPair
:
FloatPair fp1, fp2;
cin >> fp1 >> fp2;
这有点脆弱,因为如果你在输入中有非常偏离(float, float)
的格式,它将会中断。
相关文章:
- C++ 中具有 O(1) 搜索时间复杂度的数据结构
- 复杂的标准::地图,结构,标准::d问题
- 比较复杂的结构
- std::结构复杂,使编译速度变慢
- 将数据插入一些复杂的数据结构-C
- 获取从 C++ 到 C# 的复杂结构
- 将复杂的结构(带有结构的内部数组)从 C# 传递到C++
- 哪种控制结构所需的时间复杂度更低?
- 编写C 简化具有复杂层次结构的C 类的包装器,以便Cython可以称呼它
- QT:使用QVariant任意复杂的数据结构
- Calloc vs new 用于各种编译器中的复杂结构
- boost::property_tree:复杂xml结构的解析
- 在客户端和服务器之间序列化复杂的C++结构
- 如何在 boost.process 间共享内存中使用复杂结构"push_back"函数向量
- C#与C++之间的复杂结构编组
- 如何使用boost :: intercons :: vector在共享内存中分配复杂的结构
- 最短路径的dijkstra算法的时间复杂度是否取决于所使用的数据结构?
- 具有恒定时间复杂度的无向图边的数据结构
- 是否可以将复杂的 Go 结构导出/包装为 C
- 如何在c++中高效地从结构复杂的文件中读取二进制数据