直接读取对象
Reading directly to an object
我会直奔主题:
我有一个包含书名列表的文本文件。我知道如何读取文本文件,例如:
string word;
file >> word;
但是,假设我有一个名为"word"的类。是否有可能做到:
word myWord;
file >> myWord;
如果是,如何声明该对象?它会读到它包含的第一个公共字符串吗?
谢谢你的时间!
简单的答案是肯定的,你可以做file >> myWord;
,只要正如您为类定义>>
运算符时:
std::ostream&
operator>>( std::ostream& source, Word& word )
{
// ...
return source;
}
几个注意事项:
此运算符不能是成员;它必须是自由函数。(如果是成员,您的班级将是左手参数。 如果它需要访问私有数据,您可能有让它成为
friend
.不要忘记错误检查和约定
istream
错误。 如果遇到无法解析的输入进入您的班级,您需要设置std::ios::failbit
. (的当然,很多时候,你会委派给以前定义>>
,如果它们失败,std::ios::failbit
已经已设置。
编辑:
至于你应该在新重载的运算符中做什么,有几种可能性(可以小心地混合):
您可以调用现有
>>
,例如,对于字符串或内置类型。 这是迄今为止最简单的,但它假设您的输入可以很容易地根据以下方面进行唯一解析:现有的>>
,这种情况很少见。您还可以使用无格式的输入,例如
istream::get()
,这最常与前面的解决方案并行使用,输入分隔符或其他语法元素等内容您的格式。或者您可以恢复为直接从
streambuf
并解析它们。 如果您有以下情况,则适合这样做例如,一些全新的类型。 如果你走这条路,请不要忘记设置eofbit
如果您读取文件末尾,即使否则,您可以成功解析。 如果你这样做,你会还必须在>>
顶部创建一个sentry
对象,并且只有在它很好的情况下才继续。 (只有在这样的operator>>
std::ios::good
是有道理的。 你绝不能如果std::ios::good()
,请尝试从流中读取字符返回 false,并且您必须随时设置std::ios::eofbit
读取 EOF(这将导致所有将来的调用std::ios::good()
返回假)。 这太重要了,以至于我倾向于使用它使用一个小的包装器对象,并通读它。
在所有情况下,您可能都必须尝试格式化信息:举个简单的例子,如果你不想允许输入中有空格,但您仍在使用 >>
,您应该设置nows
(并在最后恢复它)。 因此,大多数这样的 >>
运算符将从保存格式状态开始,并且最后恢复它。 (这通常通过 IOSave
类,无论如何,您的工具包中都应该有它。同样,如果输入格式中的某些内容不正确,则应该设置failbit
.
作为一个简单的示例,请考虑简单Complex
的>>
.class:
std::istream&
operator>>( std::istream& source, Complex& dest )
{
IOSave state( source );
// Skip leading whitespace, depending on formatting options.
if ( (source.flags() & std::ios_base::skipws) != 0 ) {
source >> std::ws;
}
source.unsetf( std::ios_base::skipws );
std::streamsize totalWidth
= std::max( source.width() - 3, std::streamsize(0) ); ;
std::streamsize imagWidth = totalWidth / 2;
std::streamsize realWidth = totalWidth - imagWidth;
if ( source.get() != '(' ) {
source.unget();
source.setstate( std::ios::failbit );
}
double real = 0.0;
source >> std::setw( realWidth ) >> real;
std::numpunct<char> const& np
= std::use_facet<std::numpunct<char>>( source.getloc() );
if ( std::get() != (np.decimal_point() != ',' ? ',' : ';') ) {
source.unget();
source.setstate( std::ios::failbit );
}
double imag = 0.0;
source >> std::setw( imagWidth ) >> imag;
if ( std::peek() != ')' ) {
source.unget();
source.setstate( std::ios::failbit );
}
if ( source ) {
dest = Complex( real, imag );
}
return source;
}
这是一个极其简单的例子。 真正的Complex
例如,类也会接受 A+ib 形式的输入。但它应该让你了解你必须做的事情。编写这样的运算符时要考虑。
当然不是。 您必须为类word
重载>>
运算符。您可以将其作为成员函数或非成员函数执行。要以非成员身份重载,您可以编写:
fstream& operator >> (fstream& arg1,word& arg2)
{
}
如果此函数需要访问word
的私有成员,您可以使用:
class word{
// somewhere in your class add this line
friend fstream& operator >> (fstream&,word&);
}
- 如何在C++中从文件中读取/写入多个对象
- 使用对象文件读取三角形数据网格
- 如何从文件中读取两个字符串和数字数组,并将它们存储在对象向量中
- 我可以读取静态对象中的文件.txt吗?C++
- 从对象C++中的文件读取内容时出现分段错误
- 如何从文件中读取指向对象的指针?
- 如何在 C++ 中使用提升属性树从 JSON 文件中读取对象数组
- 从一个文件中读取多个序列化对象
- 读取互斥对象范围之外的volatile变量,而不是std::atomic
- 用rapidjson读取子对象向量
- 使用 OpengGLES2(角度)从帧缓冲区对象读取
- C++两次从文件保存对象读取多重继承
- 通过 ifstream 对象读取C++中的文件
- 将C 对象读取到随机访问文件中
- 使用 C++ 将对象读取和写入二进制文件
- C++在尝试编写对象读取器时,在尝试从一个向量获取数据时出错
- Boost.python 将对象拉取到本地范围内以进行读取访问
- 为什么这个ifstream无法将平面对象读取到内存中
- 如何在C++中从istream对象读取时检测空行
- C++使用fstream对象读取和写入文本文件时出现问题