我想使用ofstream在cpp中创建一个文本文件

时间:2018-02-02 17:35:26

标签: c++

我想创建一个文件qbc.txt。我知道如何创建它,但我想创建一个程序,如果一个文件已经存在同名,它会将它重命名为qbc(1).txt。

4 个答案:

答案 0 :(得分:1)

在C ++ 17中,boost的文件系统库标准化为std::filesystem

它带有方便的std::filesystem::exists功能。

它接受一个std::filesystem::path对象,但幸运的是,这些对象可以用std::string构建,使我们的程序变得简单:

std::string prefix = "qbc";
std::string extension = ".txt";
std::filesystem::path filename{prefix + extension};
int i = 0;
while (std::filesystem::exists(filename)){
    filename = prefix + "(" + std::to_string(++i) + ")" + extension;
}

// now filename is "qbc(1)" or "qbc(2)" etc.

不幸的是,在撰写本文时,没有编译器完全支持它!

答案 1 :(得分:0)

这是一个简单的解决方案。 file_exists()函数来自@Raviprakash的回复。我已经添加了如何更改文件名并重试直到成功。我以前在Python中做过类似的方法。

如果您知道您的程序是唯一一个将创建或删除这些文件的程序,那么您可以缓存最后创建的程序,只需创建下一个程序而不是每次都循环遍历所有创建的程序。但是,如果您打算以这种方式制作数十万个文件,那么这种优化才有意义。

#include <fstream>
#include <string>

bool file_exists(const std::string &filename) {
  std::ifstream in(filename);
  return in.good();
}

std::ofstream& open_new(std::ofstream &out, std::string prefix,
                        std::string suffix)
{
  std::string filename = prefix + suffix;
  unsigned int index = 0;
  while (file_exists(filename)) {
    index++;
    filename = prefix + "(" + std::to_string(index) + ")" + suffix;
  }
  out.rdbuf()->open(filename, std::ios_base::out);
  return out;
}

int main() {
  std::string prefix = "qbc";
  std::string suffix = ".txt";
  std::ofstream out;
  open_new(out, prefix, suffix);
  out << "hello world!\n";
  return 0;
}

答案 2 :(得分:0)

我知道该计划需要一些改进,但总体思路在这里:

    #include <fstream>
    #include <string>

    using namespace std;

    inline bool file_exists(const std::string& name)
    {
        ifstream f(name.c_str());
        return f.good();
    }

    int main()
    {
        string filename, name;
        name = "qbc";
        filename = name;

        int counter = 1;
        while (file_exists(filename+".txt")) {
            string str = to_string(counter);
            filename = name+ "(" + str + ")";
            counter++;
        }

        filename += ".txt";

        ofstream out(filename.c_str());

        return 0;
    }

答案 3 :(得分:0)

我不认为只使用标准库就可以完全解决这个问题。您当然可以继续选择一个新的文件名,直到找到一个未使用的文件名,然后创建新文件(如其他答案所示)。

但是这种方法存在固有的竞争条件。如果另一个进程在程序确定名称可用的时间与实际创建文件的时间之间创建文件,该怎么办?想象一下你的程序的两个副本都试图写出文件。

您需要的是一种原子方法来检查文件是否存在以及创建文件。通常的方法是首先尝试创建文件然后查看您是否成功。不幸的是,我不认为标准的C ++或C库为您提供了足够的工具。 (我很高兴被证明是错误的。)

操作系统通常提供用于执行此操作的API。例如,Windows有GetTempFileName,它只是在成功之前不断尝试创建新文件。关键是,一旦成功,它会保持文件打开,以便它知道没有其他进程可以窃取已被选中的名称。

如果您告诉我们您正在使用哪种操作系统,我们可能会提供更详细的答案。