如何在C++中使用向量获取文件中已知单词的正确位置?
问题分析与解决方案
我明白你现在的困扰啦——用ifile.tellg()获取到的单词位置总是不对,这其实是因为你调用tellg()的时机出错了!
为什么当前代码得不到正确位置?
当你用ifile >> word读取单词时,C++输入流会自动跳过所有空白字符(空格、换行、制表符这些),从第一个非空白字符开始读,直到遇到下一个空白才停止。这时候调用tellg(),得到的是单词读完之后的文件位置,而不是单词在文件里的起始位置,所以显示出来的位置自然和实际不符。
修正后的代码
我们只需要调整记录位置的时机:在读取单词之前,先定位到单词的起始位置,再记录下来。修改后的ReadTxtFile()函数如下:
void WordStats::ReadTxtFile() { std::ifstream ifile(Filename); if (!ifile) { std::cerr << "Error Opening file " << Filename << std::endl; exit(1); } std::string word; while (true) { // 跳过所有空白字符,定位到下一个单词的开头 ifile >> std::ws; if (!ifile) break; // 到达文件末尾就退出循环 // 记录单词的起始位置 std::streampos word_start_pos = ifile.tellg(); // 读取单词 if (!(ifile >> word)) break; // 将单词转为小写 std::transform(word.begin(), word.end(), word.begin(), ::tolower); // 选择对应的容器(已知/未知单词) WordMap& Words = (Dictionary.count(word) ? KnownWords : UnknownWords); // 将位置转为int存入vector(注意:streampos在部分平台可能是64位,这里转int需确保文件大小不超过int范围) Words[word].push_back(static_cast<int>(word_start_pos)); } std::cout << KnownWords.size() << " known words read." << std::endl; std::cout << UnknownWords.size() << " unknown words read." << std::endl; }
关键修改点说明
- 使用
std::ws操纵符:它会跳过输入流中所有的空白字符,确保文件指针刚好停在单词的第一个字符上。 - 提前记录位置:在调用
ifile >> word读取单词之前调用tellg(),这样得到的就是单词在文件中的起始位置。 streampos转int:tellg()返回的是std::streampos类型,我们把它转成int存入你的vector<int>中,对于普通文本文件来说这个转换是安全的,除非你的文件特别大(超过int的取值范围)。
这样修改后,你再调用DisplayKnownWordStats()函数,就能正确显示每个单词在test.txt中的起始位置啦!
内容的提问来源于stack exchange,提问作者muzzi
相关产品推荐
相关产品推荐

