2009-10-16 328 views
2

我正在尝试使用ofstream类将一些东西写入文件,但所发生的只是文件被创建,然后什么都没有。我有一些简单的代码在这里:为什么ofstream有时会创建文件但无法写入文件?

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

当我创建一个控制台应用程序,一切工作正常,所以我怕这个代码是不能完全代表。但是,我在一个更大的项目中使用这样的代码 - 说实话 - 我不完全理解(Neurostim)。我应该编写一些编译成可以由Neurostim加载的dll的类。

当代码运行时,会创建“test.txt”,然后“没有错误!”被打印出来,因为这显然是来自strerror的输出。显然这是错误的。该应用程序运行完美否则,并没有分阶段的事实,我试图写入一个损坏的流。它只是不这样做。在我看来,权限没有问题,因为该文件实际上已经创建。

有没有人有任何想法什么样的事情可能会导致这种奇怪的行为? (我在WinXP Pro SP3上并使用Visual C++ 2008 Express Edition)

谢谢!

+0

本质上,你发布的代码示例工作?老兄..请重复错误! – Jacob 2009-10-16 16:41:10

+0

我可以发布整个项目,但我想你们不想为我编写数千行代码。代码示例是为了说明发生了什么以及应该发生什么。部分问题正是因为我不知道是什么导致了这个错误,我不知道如何重现它。这就是为什么我要求可能导致这种行为的事情。 – Jordi 2009-10-16 17:55:58

回答

4

只是一个想法: - 在你真正的代码是您在流对象重新使用?

如果是这样,则需要确保在重新使用该对象之前在流上调用clear(),否则,如果出现以前的错误状态,则不起作用。我记得,在这样的数据流上不会调用clear()会导致无法写入的空文件,就像您在问题中所描述的那样。

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

只是一个尼特:你可以把它组合成一个单一的行。 ofstream file("test.txt");

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

你的测试是向后的。如果file是真的,它是开放的,并准备好写作。

此外,我不会指望strerror()在Windows上正常工作。大多数Windows API不使用errno来指示错误。如果你的失败发生在C/C++运行时库之外,这可能不会告诉你任何有趣的事情。

+0

感谢您的意见。第一件事是故意的,因为在真正的应用程序中'file'是一个类属性,所以它已经在头文件中声明,我只能在以后打开某些东西。我修复了向后检查,在我的真实代码中它确实是正确的。我实际上不知道strerror()做了什么,但是我在相关问题的某个地方看到了它(没有解决方案),并且认为我会用它来提供更多信息。 – Jordi 2009-10-16 17:52:00

+0

我想说你应该让你的测试程序可靠地重现错误,然后再试一次。至于strerror(),这在Unixy系统中最为常见,其中来自操作系统和RTL的*每个*错误都用errno表示。在Windows上,您希望查看诸如GetLastError()之类的内容。 – 2009-10-16 18:06:05

0

UPDATE更多地考虑这一点,未能通过fstreams打开一个文件并不保证设置errno。有可能errno最终在某些平台上设置(特别是如果这些平台使用FILE*或文件描述符或其他某些设置为errno的库执行fstream操作),但不能保证。检查失败的官方方法是通过​​,std::io_statestd::fstream(如failbad)的帮助方法。不幸的是,您无法从errno中获得尽可能多的信息,std::streams

你有if语句错误。如果该文件不可写,则返回operator void*返回NULL(又名false)。如果文件是可写的,则它返回非零(又名true)。所以,你想:

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

或者:

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

是的,谢谢你,我在我的问题中反思了它,但不是在我的实际代码中。我现在修好了,但问题依然存在。 – Jordi 2009-10-16 17:52:55