【问题标题】:fstream is not creating a file in C++fstream 没有在 C++ 中创建文件
【发布时间】:2015-03-03 14:00:11
【问题描述】:

我已经检查了几个这样的问题,例如: Link 1Link 2

但是他们的回答都没有帮助我。在调试了这么多小时后,我无法检测到错误。 所以,我又在这里问了。

我的程序代码是:

#include<iostream>
#include<fstream>
#include<string.h>

using namespace std;

int main(){
    ofstream file;
    file.open("data.dat",fstream::out);
    file<<fflush;
    if(!file)
        cout<<"error"<<strerror(errorno);
    file.close();
    return 0;
}

这是处理文件处理程序的主要部分。程序的其余部分处理一些数据并将其写入文件,我认为这既不相关也不影响文件处理。

有趣的是程序没有闪烁任何错误。

【问题讨论】:

  • 可能文件已创建,但不在您期望的位置?
  • 如果您从命令行运行该程序,则该文件将在当前目录中创建。如果从 IDE 运行它,则当前目录在项目设置中设置。
  • @Gaurav,不能保证 iostreams 设置 errno 时出错。并且该文件是在当前工作目录中创建的,该目录不一定是程序所在的目录(如果您运行/bin/ls,它不会默认向您显示/bin的内容!)
  • 虽然有一些问题:您不应该将 fflush 写入文件。它是您用作fflush(FILEstruct); 的C 库中的一个函数。执行代码时,它只是将 1 写入文件。此外,您不应该无条件地写入文件。检查文件是否可以先打开,如果是,则写入文件并仅在这种情况下关闭它。
  • @Gaurav 好吧,卸载并不一定意味着删除配置文件。无论如何,如果您想更改此行为,请向您最喜欢的搜索引擎询问 Code::Blocks 构建路径,而不是仅仅重新安装它。

标签: c++ file-io fstream


【解决方案1】:

您的代码通常只需稍作改动即可工作,该文件只是在运行程序的当前工作目录中创建,而不是在可执行文件所在的目录中。不过,您可能还需要解决很多其他问题:

#include <iostream>
#include <fstream>
// if including things from the C standard library in a C++ program,
// use c[header] instead of [header].h; you don't need any here though.

using namespace std;

int main()
{
    // no need to call open(), the constructor is overloaded
    // to directly open a file so this does the same thing
    ofstream file("data.dat");

    if(!file)
    {
        cout << "Couldn't open file" << endl;
        return 1;
    }

    file.close();

    // return 0; is not needed, your program will automatically
    // do this when there is no return statement
}

有关无法打开文件的原因的详细信息,您可以查看std::basic_ios::bad()std::basic_ios::fail()。在使用 C++ 流进行文件处理时,检查 errno 不是您想做的事情。

【讨论】:

    【解决方案2】:
    int main(){
        ofstream file;
        file.open("data.dat") // no need to call for ofstream ->fstream::out
        // file<<fflush; fflush won't work since there is nothing unwriten
        if(!file.is_open()) // use is_open();
            cout<<"error"<<strerror(errorno);
        // write something to file
        file << " ";
        file.close();
        return 0;
    }
    

    【讨论】:

    • fflusherrorno 仍然是错误的(参见上面的 cmets)
    • 这并没有解决实际问题,仍然是可怕的代码。
    • @amchacon 是的,应该,我更喜欢 is_open() 因为它更具可读性
    【解决方案3】:

    如果文件被打开,您可以在GDBprocfs 的帮助下找到它的位置。只需在文件打开和未关闭的位置放置一个断点。在调试器上运行程序,直到触发断点。然后使用以下命令:

    ls -l /proc/<pid>/fd
    

    其中&lt;pid&gt; 是程序的PID。文件的完整路径应该在输出中的某处。

    【讨论】:

      【解决方案4】:
      #include <iostream>
      #include <fstream>
      #include <string.h>
      #include <errno.h>
      
      int main (int argc, char* argv[])
      {
              std::ofstream file;
              file.open("data.dat", std::fstream::out);
              file << "Hello" << std::endl;
      
              if (!file)
                      std::cout << "error" << strerror(errno);
              file.close();
              return 0;
      }
      

      主要区别:

      • 你没有#include &lt;errno.h&gt;.
      • 您将“errorno”传递给 strerror(),而不是“errno”,这是正确的数字。

      这适用于 Ubuntu 14.04(64 位)。我使用没有标志的 g++ 编译。

      另外,我建议你永远不要使用 using namespace std; 一旦你开始与其他库集成,例如 Boost(Boost 的库可以与每个 C++ 标准库重叠),这可能会非常烦人特征)。

      【讨论】:

      • 好吧,你“修复”了命名空间的东西,但是你的程序和不包含 errno 标头的原始程序一样坏了。您修复了缺少的 errno 包含,但您在全局命名空间中缺少 &lt;cstdio&gt;std::fflush&lt;stdio.h&gt;fflush。我知道这确实可以编译,但是您依赖的编译器包括一个在 std 命名空间中定义 fflush 的标头,作为其他标头之一的一部分,这不是一件好事。
      • 我也建议你用-Wall -Wextra -pedantic编译,它会告诉你file &lt;&lt; std::fflush不是一个好主意,没有理由使用int main (int argc, char* argv[])而不是int main()时您不会以任何方式使用命令行参数。
      • 顺便说一句,std::flush 是在 中定义的,所以我不明白它有什么问题?我也只是喜欢使用 (int argc, char* argv[]) 来提醒自己标准实现(所以我不会开始变得懒惰并最终只使用 main())。提醒自己,我可以创建命令行应用程序也很好,它也让其他人知道这也是可能的。
      • 你从哪里得到std::fflush&lt;ostream&gt;中定义的信息?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      相关资源
      最近更新 更多