简体   繁体   English

为什么ofstream有时会创建文件却无法写入文件?

[英]Why does ofstream sometimes create files but can't write to them?

I'm trying to use the ofstream class to write some stuff to a file, but all that happens is that the file gets created, and then nothing. 我正在尝试使用ofstream类将一些内容写入文件,但是所有发生的事情就是创建了文件,然后什么也没有。 I have some simply code here: 我在这里有一些简单的代码:

#include <iostream>
#include <fstream>

#include <cstring>
#include <cerrno>

#include <time.h>

using namespace std;

int main(int argc, char* argv[])
{
    ofstream file;
    file.open("test.txt");
    if (!file) {
        cout << strerror(errno) << endl;
    } else {
        cout << "All is well!" << endl;
    }

    for (int i = 0; i < 10; i++) {
        file << i << "\t" << time(NULL) << endl;
    }

    file.flush();
    file.close();
    return 0;
}

When I create a console application, everything works fine, so I'm afraid this code is not completely representative. 当我创建一个控制台应用程序时,一切工作正常,因此恐怕这段代码并不完全具有代表性。 However, I am using code like this in a much larger project that - to be honest - I don't fully understand (Neurostim). 但是,我在一个更大的项目中使用了这样的代码,老实说,我并不完全理解(Neurostim)。 I'm supposed to write some class that is compiled to a dll which can be loaded by Neurostim. 我应该写一些编译成dll的类,该类可以由Neurostim加载。

When the code is run, "test.txt" is created and then "No error!" 运行代码时,将创建“ test.txt”,然后创建“无错误!”。 is printed, as this is apparently the output from strerror. 被打印,因为这显然是strerror的输出。 Obviously this is wrong however. 但是,显然这是错误的。 The application runs perfectly otherwise, and is not phased by the fact that I'm trying to write to a corrupted stream. 该应用程序在其他情况下可以完美运行,并且不会因我试图写入损坏的流而分阶段进行。 It just doesn't do it. 它只是不这样做。 It seems to me like there is no problem with permissions, because the file is in fact created. 在我看来,权限没有问题,因为文件实际上是创建的。

Does anyone have any ideas what kind of things might cause this odd behavior? 有谁知道什么样的事情会导致这种奇怪的行为? (I'm on WinXP Pro SP3 and use Visual C++ 2008 Express Edition) (我在WinXP Pro SP3上,并使用Visual C ++ 2008 Express Edition)

Thanks! 谢谢!

Just a thought :- in your real code are you re-using your stream object? 只是想一想:-在您的真实代码中,您是否正在重用流对象?

If so, you need to ensure that you call clear() on the stream before re-using the object otherwise, if there was a previous error state, it won't work. 如果是这样,则需要确保在重用该对象之前在流上调用clear() ,否则,如果以前存在错误状态,它将无法正常工作。 As I recall, not calling clear() on such a stream would result in an empty file that couldn't be written to, as you describe in your question. 我记得,不对此类流调用clear()会导致无法写入一个空文件,正如您在问题中所描述的那样。

    ofstream file;
    file.open("test.txt");

Just a nit: you can combine that into a single line. 仅此而已:您可以将其合并为一行。 ofstream file("test.txt");

    if (file) {
            cout << strerror(errno) << endl;
    } else {
            cout << "All is well!" << endl;
    }

Your test is backwards. 您的测试是倒退的。 If file is true, it's open and ready for writing. 如果file为true,则表示file已打开并可以写入。

Also, I wouldn't count on strerror() working correctly on Windows. 另外,我也不会指望strerror()在Windows上能正常工作。 Most Windows APIs don't use errno to signal errors. 大多数Windows API都不使用errno来指示错误。 If your failure is happening outside the C/C++ run-time library, this may not tell you anything interesting. 如果您的故障发生在C / C ++运行时库之外,则可能不会告诉您任何有趣的事情。

UPDATE Thinking more about this, failing to open a file via fstreams is not guaranteed to set errno . 更新考虑这件事,不能保证无法通过fstreams打开文件,不能设置errno It's possible that errno ends up set on some platforms (espeically if those platforms implement fstream operations with FILE* or file descriptors, or some other library that sets errno ) but that is not guaranteed. errno可能会在某些平台上设置(特别是如果那些平台使用FILE*或文件描述符或其他设置errno库来实现fstream操作),但这并不能保证。 The official way to check for failure is via exceptions , std::io_state or helper methods on std::fstream (like fail or bad ). 检查失败的官方方法是通过exceptionstd::io_statestd::fstream上的helper方法(例如failbad )。 Unfortunately you can't get as much information out of std::streams as you can from errno . 不幸的是,您无法从errno中从std::streams获得尽可能多的信息。

You've got the if statement wrong. 您的if语句错误。 operator void* returns NULL (aka false ) if the file is not writable. 如果文件不可写, operator void*返回NULL (即false )。 It returns non-zero (aka true ) if the file is writeable. 如果文件是可写的,则返回非零(即true )。 So you want: 所以你要:

if (!file) {
        cout << strerror(errno) << endl;
} else {
        cout << "All is well!" << endl;
}

Or: 要么:

if (!file.good()) {
        cout << strerror(errno) << endl;
} else {
        cout << "All is well!" << endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM