0

我有一个小程序,用于从文件中复制一个小短语,但似乎我对seekg()的工作方式有误解,或者我的代码中存在问题,导致该函数无法按预期工作。

文本文件包含:

//介绍

以前注意=假

该代码旨在将单词“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 个索引处,这是短语“false”开始的地方。然后程序将从该索引开始输入,直到遇到空格字符,或者遇到文件末尾。

实际发生了什么:

无论出于何种原因,get 指针在预期之前启动了一个索引。我不确定为什么。非常感谢您解释出了什么问题/我做错了什么。

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

4

2 回答 2

2

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

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

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

于 2014-08-20T19:58:09.903 回答
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)并使用适当的库来解析它们来节省编程类型。

于 2014-08-20T19:57:10.463 回答