为std :: ifstream表示“只读,不修改位置”

时间:2014-01-30 12:22:57

标签: c++ c++11 const fstream ifstream

在我的代码中,我想在确定如何读取文件之前识别有关文件内容的一些属性。 (也就是说,我搜索了一个关键字,如果找到,则会使用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*); 不表示常量。如何调整我的方法来表达(在界面级别)该方法不会改变当前状态?

2 个答案:

答案 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。它确实在多线程程序中有所作为。