C ++文件处理,is_open返回错误

时间:2012-01-27 22:00:50

标签: c++ file-io

如果我在我的代码中包含if测试,则返回错误消息,我不知道为什么。 当它没有被使用时,我的程序被卡在一个永远不会到达文件末尾的循环中。我不明白出了什么问题。

int countlines()
{
    fstream myfile;
    myfile.open("questions.txt", ios::in);
    string contents;
    int linenumber = 0;

    //if (myfile.is_open())  
    // {
    while (!myfile.eof())  
    {
        getline( myfile, contents );
        if (contents != "")
        {
            linenumber++;
        }
    }
    cout << "there are " << linenumber << " lines.\n";
    //}else {cout<<"Unable to get file.\n";}

    myfile.close();
    return(linenumber);
}

4 个答案:

答案 0 :(得分:3)

发生的事情是您的文件未被打开。这就是is_open失败的原因。

然后,当你注释掉支票时,你正在打破你的循环,因为你的迭代不正确(参见我的评论)而没有检测到流失败(.eof() 永远不会该流上的true

确保文件位于正确的位置,并且可以访问。

答案 1 :(得分:2)

使用std::istreamstd::ostream(其std::fstream实现)时,建议的用法是直接在bool上下文中使用流而不是调用eof()函数,因为它只有在您设法读取文件的最后一个字节时才返回true。如果之前有任何错误,该函数仍将返回true

所以,您应该将代码编写为:

int countlines() {
    ifstream myfile;
    int linenumber = 0;
    string linecontent;
    myfile.open("question.txt", ios::in);
    while (getline(myfile, linecontent)) {
        if (!linecontent.empty()) {
            ++linenumber;
        }
    }
    return linenumber;
}

答案 2 :(得分:2)

在C ++中逐行读取文件的正确习惯是使用这样的循环:

for (std::string line; std::getline(file,line);)
{
    // process line.
}

在您的示例中插入此内容(+修复缩进和变量名称),如下所示:

int countlines(const std::string& path)
{
    // Open the file.
    std::ifstream file(path.c_str());
    if (!file.is_open()) {
        return -1; // or better, throw exception.
    }

    // Count the lines.
    int count = 0;
    for (std::string line; std::getline(file,line);)
    {
        if (!line.empty()) {
            ++count;
        }
    }

    return count;
}

请注意,如果您不打算处理行内容,实际上可以使用std::streambuf_iterator跳过处理它们,这可以使您的代码看起来像:

int countlines(const std::string& path)
{
    // Open the file.
    std::ifstream file(path.c_str());
    if (!file.is_open()) {
        return -1; // or better, throw exception.
    }

    // Refer to the beginning and end of the file with
    // iterators that process the file character by character.
    std::istreambuf_iterator<char> current(file);
    const std::istreambuf_iterator<char> end;

    // Count the number of newline characters.
    return std::count(current, end, '\n');
}

第二个版本将完全绕过复制文件内容,避免为长行分配大块内存。

答案 3 :(得分:0)

尝试以下代码。它(希望)也会让你知道为什么文件打开失败......

int countlines()
{
    ifstream myfile;
    myfile.open("questions.txt");
    string contents;
    int linenumber = 0;

    if (myfile.is_open())  
    {
        while (getline(myfile, contents))  
        {
            if (contents != "")
                linenumber++;
        }
        cout << "there are " << linenumber << " lines." << endl;        
        myfile.close();
    }
    else
        cout << "Unable to get file (reason: " << strerror(errno) << ")." << endl;

    return linenumber;
}