C++ 为什么使用while(!input.eof())循环两次都不起作用?

C++ 为什么使用while(!input.eof())循环两次都不起作用?,c++,iostream,C++,Iostream,下面几行代码旨在将输入文本文件中的每个单词(单词由新行分隔)放入字符串向量中,然后将每个单词翻过来,并查看这个翻过来的单词是否包含在输入文件中的单词列表中 我相信我的二进制搜索函数和wordTurn函数工作得很好。 我对代码做了几个简单的测试,发现使用while(!myFile.eof())循环两次可能是导致代码无法工作的原因。不工作是指我将输出文件(“pairs.txt”)作为一个空文档(它应该是一个成对单词的列表) 也就是说,当我在第二个while(!myFile.eof())循环体中放入一

下面几行代码旨在将输入文本文件中的每个单词(单词由新行分隔)放入字符串向量中,然后将每个单词翻过来,并查看这个翻过来的单词是否包含在输入文件中的单词列表中

我相信我的二进制搜索函数和wordTurn函数工作得很好。 我对代码做了几个简单的测试,发现使用while(!myFile.eof())循环两次可能是导致代码无法工作的原因。不工作是指我将输出文件(“pairs.txt”)作为一个空文档(它应该是一个成对单词的列表)

也就是说,当我在第二个while(!myFile.eof())循环体中放入一些简单的打印代码时,它没有打印出来,因此我得出结论,这个循环没有到达。这更有可能,因为它是在我注释掉第一个while(!myFile.eof())循环时打印的。我最初将第一个while循环放置在else主体上,但这没有什么区别

你认为问题出在哪里? 我尝试将这两个循环体合并到第二个循环中,它在输出文件中生成了一些内容,但这不是这段代码应该做的,这在逻辑上是不正确的

任何建议都将不胜感激

int main(int argc, char* argv[]) {

    vector<string> words;
    ifstream myFile(argv[1]);
    ofstream outputFile("pairs.txt");
    string vocab;
    string s;
    int count;

    while(!myFile.eof()) {                //first while(!myFile.eof()) loop
        getline(myFile, s);
        words.push_back(s);
    }

    if(argc != 2) {
        cout << "Usage: provide the name of one input file after the dictlookupHN executable file." << endl;
        return (1);
    }
    else {
        if(!myFile.is_open()) {
            cerr << "Error: unable to open file " << argv[1] << endl;
            return (1);
        }
        else {
            while(!myFile.eof()) {      //second while(!myFile.eof()) loop
                getline(myFile, vocab);
                string turnedWord = wordTurn(vocab);
                if(binsearch(words, turnedWord) != "") {
                    outputFile << vocab << ":" << turnedWord << endl;
                    count++;
                }
            }
        }

    }
    myFile.close();
    outputFile.close();

    return 0;
}
intmain(intargc,char*argv[]){
向量词;
ifstream myFile(argv[1]);
流输出文件(“pairs.txt”);
弦乐;
字符串s;
整数计数;
while(!myFile.eof()){//首先while(!myFile.eof())循环
getline(myFile,s);
字。推回;
}
如果(argc!=2){

cout第一个循环到达EOF,这是“读取标记”的位置,因此第二个EOF在第二个循环中读取为第一个

简单地说,尝试在循环之间关闭和打开文件


更好的方法是再次从顶部读取。

第一个循环到达EOF,这是“读取标记”的位置,因此第二个EOF作为第二个循环中的第一个读取

简单地说,尝试在循环之间关闭和打开文件


更好的方法是再次使用从顶部读取。

ifstream类在流数据中保留一个内部偏移量,跟踪它必须从何处读取,以便进行下一个操作

当此偏移量到达末尾时,它停止第一个循环(
eof()
返回false)。在再次读取之前,需要将此内部位置重置回文件的开头

你可以这样说:

myFile.clear(); // clear stream flags and error state
myFile.seekg(0, ios::beg); // reset read position
在第二个循环之前


编辑:添加了对
clear()

的调用。ifstream类维护流数据的内部偏移量,跟踪它必须从何处读取,以便进行下一个操作

当此偏移量到达末尾时,它停止第一个循环(
eof()
返回false)。在再次读取之前,需要将此内部位置重置回文件的开头

你可以这样说:

myFile.clear(); // clear stream flags and error state
myFile.seekg(0, ios::beg); // reset read position
在第二个循环之前


编辑:添加了对
clear()

的调用,第一个循环到达文件末尾,并且在第二次读取之前您不会重置。您需要在第一个循环之后查找文件的开头:
myFile.seekg(0,ios::beg);
将为您执行此操作。

第一个循环到达文件末尾,在第二次读取之前您不会重置。您需要在第一个循环后查找到文件的开头:
myFile.seekg(0,ios::beg);
将为您执行此操作。

当您完成文件的第一次运行时,文件的查找指针位于文件的末尾。如果要再次查找文件,需要使用
myFile.seekg(0,ios::beg)重置文件指针;
在第二个
循环之前

        ...
        else {
                myFile.seekg(0, ios::beg);
                while(!myFile.eof()) {      //second while(!myFile.eof()) loop
        ...

这应该可以解决问题。

当您完成文件的第一次运行时,文件的查找指针位于文件的末尾。如果要再次查找文件,则需要使用myFile.seekg(0,ios::beg)重置文件指针;
在第二个
循环之前

        ...
        else {
                myFile.seekg(0, ios::beg);
                while(!myFile.eof()) {      //second while(!myFile.eof()) loop
        ...

这应该可以解决问题。

如果你想再次读取文件[一旦你将整个文件读到最后],你需要重置坏/失败位,并寻找开始。文件结束是一种永久状态,除非采取措施重置它

因此,您需要
myFile.clear();
myFile.seekg(0,ios_base::beg);


虽然我觉得在这种特殊情况下,您实际上想要打开一个不同的文件,在这种情况下,我建议关闭当前文件,并使用不同的变量-它们不太昂贵,而且代码更清晰[特别是如果你称之为合理的,例如,
vocabFile
而不是
myFile
]

如果你想再次读取文件[一旦你将整个文件读到最后],你需要重置坏的/失败的位,并寻找开始。文件的结尾是一个永久状态,除非采取措施重置它

因此,您需要
myFile.clear();
myFile.seekg(0,ios_base::beg);


虽然我觉得在这种特殊情况下,您实际上想要打开一个不同的文件,在这种情况下,我建议关闭当前文件,并使用不同的变量-它们不太昂贵,而且代码更清晰[特别是如果您称之为合理的,例如
vocabFile
而不是
myFile
]

要再次从文件开头读取,请使用:

myFile.seekg(0, ios::beg);
但请注意,这不是读取文件的好方法:

string vocab;
while(!myFile.eof()) {
    getline(myFile, vocab);
    ...
}
它应该是这样的:

string vocab;
while(getline(myFile, vocab)) {
    if (vocab.empty())
        continue;               // empty line might be read
    ...
}

查看:

要再次从文件开头读取,请使用:

myFile.seekg(0, ios::beg);
但请注意,这不是读取文件的好方法:

string vocab;
while(!myFile.eof()) {
    getline(myFile, vocab);
    ...
}
它应该是这样的:

string vocab;
while(getline(myFile, vocab)) {
    if (vocab.empty())
        continue;               // empty line might be read
    ...
}
看看:

谢谢你