seekg()没有按预期工作

时间:2014-08-20 19:48:14

标签: c++ visual-c++ fstream seekg

我有一个小程序,用于从文件中复制一个小短语,但似乎我对 seekg()的工作原理有误导,或者出现问题我的代码阻止函数按预期工作。

文本文件包含:

  

//简介

     

previouslyNoted =假

该代码旨在复制单词" false"成为一个字符串

std::fstream stats("text.txt", std::ios::out | std::ios::in);
//String that will hold the contents of the file
std::string statsStr = "";
//Integer to hold the index of the phrase we want to extract
int index = 0;

//COPY CONTENTS OF FILE TO STRING
while (!stats.eof())
{
    static std::string tempString;
    stats >> tempString;
    statsStr += tempString + " ";
}

//FIND AND COPY PHRASE
index = statsStr.find("previouslyNoted=");     //index is equal to 8
//Place the get pointer where "false" is expected to be
stats.seekg(index + strlen("previouslyNoted="));     //get pointer is placed at 24th index
//Copy phrase
stats >> previouslyNotedStr;

//Output phrase
std::cout << previouslyNotedStr << std::endl;

但无论出于何种原因,该计划输出:

  

=假

我期望发生的事情:

我相信我把get指针放在文件的第24个索引处,这就是短语&#34; false&#34;开始。然后程序将从该索引向前输入,直到满足空格字符,或者文件的结尾已经满足。

实际发生了什么:

无论出于何种原因,get指针在预期之前启动索引。而且我不确定为什么。我将非常感谢您对错误/我做错的解释。

此外,我确实理解我可以简单地将 previousNotedStr 设为 statsStr 的子字符串,从我希望的位置开始,我已经尝试过成功。我真的只是在这里做实验。

2 个答案:

答案 0 :(得分:2)

VisualC ++标记表示您在Windows上。在Windows上,行尾有两个字符(\ r \ n)。当您一次读取字符串中的文件时,此行结束序列将被视为分隔符,并将其替换为单个空格字符。

因此,在您读取文件后,statsStr与文件内容不匹配。每个文件中都有新行的地方,你用一个字符替换了两个字符。因此,当您使用seekg根据您从statsStr字符串中获得的数字将自己定位在文件中时,您最终会出错。

即使您的新行处理正确,如果文件包含两个或多个连续的空白字符,您仍会遇到问题,因为这些字符将被读取循环折叠为单个空格字符。

答案 1 :(得分:1)

您正在逐字阅读文件。有更好的方法:

while (getline(stats, statsSTr)
{
  // An entire line is read into statsStr.
  std::string::size_type posn = statsStr.find("previouslyNoted=");
  // ...
}

通过将整个文本行读入字符串,无需重新定位文件。

此外,在逐字阅读时会出现空白问题。这将影响认为文本在文件中的位置。例如,跳过空格,并且无法分辨跳过了多少空格,换行符或制表符。

顺便说一句,甚至不要考虑替换同一文件中的文本。仅当替换文本与文件中的原始文本具有相同的长度时,替换文本才有效。写一个新文件。

编辑1:
更好的方法是将字符串声明为数组。这有助于在字符串中定位指针:

static const char key_text[] = "previouslyNoted=";
while (getline(stats, statsStr))
{
  std::string::size_type key_position = statsStr.find(key_text);
  std::string::size_type value_position = key_position + sizeof(key_text) - 1; // for the nul terminator.
  // value_position points to the character after the '='.
  // ...
}

您可能希望通过使数据文件符合现有格式(如INI或XML)并使用适当的库来解析它们来保存编程类型。