web-dev-qa-db-ja.com

fopenで必要なすべてのフォルダを作成するには

fopen("aaa\bbb\ccc\myfile.txt","w")を使用して出力ファイルを作成しています。ただし、フォルダaaabbb、およびcccは存在しません。この問題を解決するための最良の方法は何ですか? fopenに必要なすべてのフォルダを作成するように依頼する標準的な方法はありますか?

16
vico

他の人が指摘しているように、C標準ライブラリのディレクトリに対するクロスプラットフォームのサポートはありません。

私の理解では、fopen()とその友人は、指定したパスの_/_- esまたは_\_- esがディレクトリとして使用されていることを知りません。現在使用されている2つの主要なオペレーティングシステムファミリのセパレータ。

singleディレクトリ作成のクロスプラットフォームソリューションについては、@ dbushの answer を参照してください。

次に、これを独自の関数でラップして、すべての親フォルダーを含む完全なファイル/ディレクトリパスを取得し、必要なすべての親フォルダー(必要な場合)を1つずつ作成します。

このためには、ファイルパスから、最上部/左端のディレクトリから始めて、連続する各親ディレクトリを抽出する方法を考案する必要があります。 strtok()のような関数は安全ではない可能性があるため、Cで文字列を分割する場合は注意が必要です。作成するディレクトリのリストにパスを変換するには、別の方法を使用する方がよい場合があります。

また、ディレクトリがすでに存在する場合や、ディレクトリの1つを配置するパスにファイルが存在する場合にも対処する必要がある場合があります。

1
saxbophone

C標準Lib。ファイルを開いたり書き込んだりするための関数。既存のディレクトリに新しいファイルを作成することはできますが、新しいディレクトリを作成することはできません。これを行うには、ヘッダー「sys /stat.h」の「mkdir」関数とヘッダー「unistd.h」の「chdir」関数を使用することをお勧めします。

たとえば、Windows 10のCygwinで使用するCプログラムを作成する場合、次のように機能します。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <error.h>
int main (void)
{
   FILE * fp;
   chdir("/cygdrive/d");
   if (mkdir("aaa", S_IRWXU|S_IRWXG|S_IROTH))
   {
      error(EXIT_FAILURE, errno, "Failed to create directory aaa");
   }
   chdir("aaa");
   if (mkdir("bbb", S_IRWXU|S_IRWXG|S_IROTH))
   {
      error(EXIT_FAILURE, errno, "Failed to create directory bbb");
   }
   chdir("bbb");
   if (mkdir("ccc", S_IRWXU|S_IRWXG|S_IROTH))
   {
      error(EXIT_FAILURE, errno, "Failed to create directory ccc");
   }
   chdir("ccc");
   fp=fopen("MyFile.txt", "w");
   if (!fp)
   {
      error(EXIT_FAILURE, errno, "Failed to open file for writing");
   }
   fprintf(fp, "Test.\n");
   fclose(fp);
   return 0;
}

これにより、ディレクトリ「D:\ aaa\bbb\ccc」が作成され、そのディレクトリに「MyFile.txt」というファイルが作成され、そのファイルに「Test。\ n」と書き込まれます。

0
Robbie Hatley

おそらく他のものほどエレガントではありませんが:

_system("mkdir aaa\\bbb\\ccc\\");
FILE * fp;
fp = fopen("aaa/bbb/ccc/myfile.txt","w");
_

Linuxの場合は、_-p_オプションとスラッシュを使用します。

編集:Windowsを使用している場合は、バックスラッシュをsystem()関数に含める必要があります

0
C Chorche

プログラムにC++を混在させることができる場合、boost.filesystemライブラリにはすべての中間ディレクトリを作成するための非常に便利な function があります。

bool create_directories(const path&p);

0
Tanveer Badar