我有一个小程序,用于从文件中复制一个小短语,但似乎我对 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 的子字符串,从我希望的位置开始,我已经尝试过成功。我真的只是在这里做实验。
答案 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)并使用适当的库来解析它们来保存编程类型。