gpt4 book ai didi

c++ - 直接读取对象

转载 作者:搜寻专家 更新时间:2023-10-31 01:07:54 25 4
gpt4 key购买 nike

我开门见山:

我有一个包含书名列表的文本文件。我知道如何读取文本文件,例如:

string word;
file >> word;

但是,假设我有一个名为“word”的类。是否可以这样做:

word myWord;
file >> myWord;

如果是,必须如何声明此类对象?它会读到它包含的第一个公共(public)字符串吗?

感谢您的宝贵时间!

最佳答案

简单的答案是肯定的,你可以做 file >> myWord;,只要正如您为您的类(class)定义的 >>> 运算符:

std::ostream&
operator>>( std::ostream& source, Word& word )
{
// ...
return source;
}

几个注意事项:

  • 该运算符(operator)不能是成员(member);它必须是一个自由函数。(如果是成员(member),你的类(class)就是左手参数。)如果它需要访问私有(private)数据,你可能有使其成为 friend

  • 不要忘记错误检查和约定istream 错误。如果遇到输入无法解析进入你的类(class),你需要设置std::ios::failbit。 (的当然,很多时候,你会委派给以前定义了 >>,如果它们失败了,std::ios::failbit 已经已设置。)

编辑:

至于你应该在新重载的运算符中做什么,有几种可能性(小心,可以是混合):

  • 您可以调用现有的 >>>,例如,对于字符串或内置类型。这是迄今为止最简单的,但它假设您的输入可以很容易地被唯一地解析现有的 >>>,这种情况很少见。

  • 你也可以使用无格式输入,比如istream::get(),这最常与以前的解决方案并行使用,输入分隔符或其他语法元素你的格式。

  • 或者您可以恢复为直接从streambuf,并解析它们。这是合适的,如果你有例如,一些全新的类型。如果你走这条路,做不要如果您读取文件末尾则忘记设置eofbit,即使否则你可以成功解析。如果你这样做,你会还必须在 >>> 的顶部创建一个 sentry 对象,并且只有在好的情况下才继续。 (只有在这样的operator>> std::ios::good 有意义。你绝不能如果 std::ios::good() 尝试从 streambuf 中读取一个字符返回 false,你必须随时设置 std::ios::eofbit读取 EOF(这将导致所有 future 的调用std::ios::good() 返回 false)。这是非常重要的我倾向于为它使用一个小的包装器对象,然后通读

在所有情况下,您可能都需要调整格式信息:作为一个简单的例子,如果你不想让输入中有空白,但你仍在使用 >>>,你应该设置 nows(并在最后恢复它)。因此,大多数此类>>> 运算符将从保存格式化状态开始,并且最后恢复它。 (这通常是通过一个IOSave 类,无论如何你都应该在你的工具包中。)再一次,如果输入格式不正确,你应该设置failbit

作为一个简单的例子,考虑一个 >> 一个简单的 Complex类:

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

这是一个极其简单的例子。一个真正的复杂例如,class 也接受 a+ib 形式的输入。但它应该让你了解你必须做的事情编写此类运算符时请考虑。

关于c++ - 直接读取对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18702804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com