在我的代码中,我想在确定如何读取文件之前识别有关文件内容的一些属性。 (也就是说,我搜索了一个关键字,如果找到,则会使用foo(std::ifstream&)
来阅读,而使用bar(std::ifstream&)
进行阅读。
我实现了搜索关键字
的方法bool containsKeyword(std::ifstream& file, const char* keyword)
{
for ( std::string line; std::getline(file, line); )
{
if ( line == keyword )
{
return true;
}
}
return false;
}
这会修改文件流的位置(如果找不到关键字,则结束,或者关键字的位置)。但是我想在搜索后重置位置。这可以通过ScopeGuard完成:
class FilePositionScopeGuard
{
private:
std::ifstream& file;
using FilePosition = decltype(std::declval<std::ifstream>().tellg());
FilePosition initial_position;
public:
FilePositionScopeGuard(std::ifstream& file_)
:
file(file_),
initial_position(file.tellg())
{
}
~FilePositionScopeGuard()
{
file.clear();
file.seekg(initial_position);
}
};
现在我们将其添加到方法中:
bool containsKeyword(std::ifstream& file, const char* keyword)
{
FilePositionScopeGuard guard(file);
for ( std::string line; std::getline(file, line); )
{
...
这很好,因为在方法中只有一个额外的行,无论方法如何退出(返回或异常之一),我们都会得到不修改std::ifstream
的行为。
但是,方法bool containsKeyword(std::ifstream&, const char*);
不表示常量。如何调整我的方法来表达(在界面级别)该方法不会改变当前状态?
答案 0 :(得分:3)
您可以更改签名以获取位置保护文件:
bool containsKeyword(const FilePositionScopeGuard &, const char *);
这允许调用者根据当前签名传递ifstream
(为该操作构建一个临时防护),或者自己保护并将其用于多个操作。
您需要公开ifstream
成员。
答案 1 :(得分:0)
使用文字评论// the method does read from file but resets the read pointer
。
不要指望API的用户是键盘上的猴子。特别是在方法内部强制输出constancy时,不要将ifstream
参数标记为const。它确实在多线程程序中有所作为。