gpt4 book ai didi

c++ - seekg 不转到文件开头

转载 作者:行者123 更新时间:2023-12-05 03:23:58 25 4
gpt4 key购买 nike

我正在尝试制作一个随机名称生成器。问题是为了获得文件中的行数,我必须遍历它。

所以当我需要在 getRandomName() 中再次循环获取名称时,它已经到达文件末尾

我尝试使用 seekg(0, std::ios::beg) 解决问题,但由于某种原因它不起作用。

int getLineCount(std::fstream &names) {
int count{};
while (names) {
std::string name;
getline(names, name);
++count;
};
// last line is empty
return count - 1;
}

std::string getRandomName(std::fstream &names, int lineCount) {
int randomNum{getRandomNumber(1, lineCount)};
std::string name;
names.seekg(1, std::ios::beg); // here i try to go to the beginning but it doesnt work
for (int i{0}; i < randomNum; ++i) {
names >> name;
};
return name;
};

int main() {
std::srand(static_cast<unsigned int>(std::time(nullptr)));
std::rand();
std::fstream names{"names.txt"};

int lineCount{getLineCount(names)};
std::cout << getRandomName(names, lineCount);
}

最佳答案

问题是文件流将到达文件末尾视为错误条件,并设置相应的位,包括失败位和 EOF 位。只要此状态持续存在,任何进一步的文件操作都会失败。您可以通过 clear ing 将流设置回正常运行状态不过,错误状态 - 如果您这样做,那么您将能够按预期进行。

如果需要经常进行这些查找,那么可能值得考虑在 std::vector<std::string> 中缓冲数据行– 除非你必须处理非常大的数据(从而引发分页效应),否则这会更有效率。即使具有分页效果,但有足够大的可用磁盘空间,您仍然可以更好地进行每次查找,因为您最多只能从磁盘加载一个内存页面。

如果你只需要查找一次,那么你可能不需要 getLineCount完全发挥作用——从整个最大范围中选择一个随机值,然后计算行数,直到找到所需的行——到达文件末尾。如果发生后者,则根据找到的行数重新计算随机索引并再次遍历文件。你的文件越大,你只需要迭代一次的机会就越大,如果你仍然需要做两次,无论如何都不会丢失任何东西......但是请注意,这种方法需要你的随机数生成器生成均匀分布的随机数!

这也适用于多次调用,尽管随着每次进一步调用读取超过文件大小的机会至少一次增加,获益的机会会变小。

关于c++ - seekg 不转到文件开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72403576/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com