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

发布于 2024-12-29 04:59:53 字数 597 浏览 2 评论 0原文

如果我在代码中包含 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);
}

If I include the if test in my code the error message is returned and I'm not sure why.
and when it's not used, my program get's stuck in a loop where it never reaches the end of the file. I don't understand what's going wrong.

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半步萧音过轻尘 2025-01-05 04:59:53

发生的情况是您的文件没有被打开。这就是 is_open 失败的原因。

然后,当您注释掉检查时,您就会破坏循环,因为您迭代不正确(请参阅我的评论)并且没有检测到流故障(.eof()永远 在该流上为 true)。

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

What's going on is that your file is not being opened. That's why is_open fails.

Then, when you comment out the check, you're breaking your loop because you're iterating incorrectly (see my comment) and not detecting stream failures (.eof() will never be true on that stream).

Make sure that the file is in the right place, and that it is accessible.

甜味超标? 2025-01-05 04:59:53

在 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');
}

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

The correct idiom for reading a file line-by-line in C++ is using a loop like this:

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

Inserting this in your example (+fixing indentation and variable names) gives something like this:

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;
}

Note that if you don't intend to process the line contents, you can actually skip processing them using std::streambuf_iterator, which can make your code look like:

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');
}

The second version will completely bypass copying the file contents and avoid allocating large chunks of memory for long lines.

述情 2025-01-05 04:59:53

当使用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;
}

When using std::istream and std::ostream (whose std::fstream implements), the recommended usage is to directly use the stream in a bool context instead of calling eof() function because it only return true when you managed to read until the last byte of the file. If there was any error before that, the function will still return true.

So, you should have written your code as:

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;
}
家住魔仙堡 2025-01-05 04:59:53

尝试以下代码。它还(希望)让您了解为什么文件打开失败......

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;
}

Try the following code. It will also (hopefully) give you an idea why the file open is failing...

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文