3

再帰的に CreationDirectory の多くの例を見つけましたが、探していたものではありませんでした。

ここに仕様があります

与えられた入力

  1. \\サーバー\共有\aa\bb\cc
  2. c:\aa\bb\cc

ヘルパー API の使用

 CreateDirectory (char * path)
 returns true, if successful
 else
 FALSE

条件: パスがローカルかサーバー共有かを区別するための解析は行わないでください。

C または C++ でルーチンを作成する

4

8 に答える 8

7

かなり簡単だと思います...ここでは、すべてのWindowsバージョンで動作するバージョンです:

unsigned int pos = 0;
do
{
    pos = path.find_first_of("\\/", pos + 1);
    CreateDirectory(path.substr(0, pos).c_str(), NULL);
} while (pos != std::string::npos);

ユニコード:

pos = path.find_first_of(L"\\/", pos + 1);

よろしく、

于 2012-10-05T11:55:29.823 に答える
3

これはまさにあなたが望むものかもしれません。パスがローカルかサーバー共有かを区別するための解析は行いません。

bool TryCreateDirectory(char *path){
    char *p;
    bool b;

    if(
        !(b=CreateDirectory(path))
        &&
        !(b=NULL==(p=strrchr(path, '\\')))
        ){
        size_t i;

        (p=strncpy((char *)malloc(1+i), path, i=p-path))[i]='\0';
        b=TryCreateDirectory(p);
        free(p);
        b=b?CreateDirectory(path):false;
    }

    return b;
}

アルゴリズムは非常に単純です。より高いレベルのディレクトリの文字列を再帰的に渡すだけで、現在のレベルのディレクトリの作成は、1 つ成功するか、より高いレベルがなくなるまで失敗します。内部呼び出しが成功して返されたら、current を作成します。このメソッドは、ローカルまたはサーバー自体を決定するために解析しません。CreateDirectory に従っています。WINAPI では、パスがそのレベルに達したときに CreateDirectory で "c:" または "\" を作成することはできません。メソッドはすぐに path="" を使用してそれ自体を呼び出すようになり、これも失敗します。Microsoft がファイル共有の命名規則をこのように定義している理由は、DOS パス規則との互換性とコーディング作業の簡素化のためです。

于 2011-09-03T22:25:18.647 に答える
1

MakeSureDirectoryPathExists ()を使用するのはどうですか?

于 2009-10-05T14:03:13.427 に答える
1

完全にハック的で安全ではなく、本番コードで実際にやりたいことは何もありませんが...

警告: ブラウザに入力されたコードは次のとおりです。

int createDirectory(const char * path) {
  char * buffer = malloc((strlen(path) + 10) * sizeof(char));
  sprintf(buffer, "mkdir -p %s", path);
  int result = system(buffer);
  free(buffer);
  return result;
}
于 2009-10-04T23:38:39.303 に答える
0
std::pair<bool, unsigned long> CreateDirectory(std::basic_string<_TCHAR> path)
{
    _ASSERT(!path.empty());
    typedef std::basic_string<_TCHAR> tstring;

    tstring::size_type pos = 0;

    while ((pos = path.find_first_of(_T("\\/"), pos + 1)) != tstring::npos)
    {
        ::CreateDirectory(path.substr(0, pos + 1).c_str(), nullptr);
    }

    if ((pos = path.find_first_of(_T("\\/"), path.length() - 1)) == tstring::npos)
    {
        path.append(_T("\\"));
    }

    ::CreateDirectory(path.c_str(), nullptr);

    return std::make_pair(
        ::GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES,
        ::GetLastError()
        );
}
于 2011-11-18T02:24:00.267 に答える
0

ルートから始まるパスの各ディレクトリ レベルをたどって、次のレベルを作成しようとします。

CreateDirectory 呼び出しのいずれかが失敗した場合は、早期に終了できます。失敗せずにパスの最後に到達した場合は成功です。

これは、既に存在するパスで CreateDirectory を呼び出しても悪影響がないことを前提としています。

于 2009-10-04T23:25:16.367 に答える
0

サーバー名のパス名を解析しないという要件は、解析が必要であることを認めているように見えるため、興味深いもの/です。

おそらく、システムによっては精巧な認証情報がエンコードされている可能性がある、ホストとマウント ポイントの潜在的に複雑な構文のハック式を組み込むことを避けることが考えられます。

それが宿題である場合、私はあなたが考えるべきアルゴリズムを提供するかもしれませんが、それらの要件を満たす 1 つの方法は、完全なパス名を mkdir しようとすることから始めることだと思います。失敗した場合は、最後のディレクトリを切り取って再試行します。それが失敗した場合は、別のディレクトリを切り取って再試行します...最終的には、サーバーの構文を理解する必要なくルート ディレクトリに到達する必要があります。次に、パス名の追加を開始する必要があります。コンポーネントを戻し、サブディレクトリを1つずつ作成します。

于 2009-10-05T01:08:08.403 に答える
-1
void createFolders(const std::string &s, char delim) {
std::stringstream ss(s);
std::string item;
char combinedName[50]={'\0'};
while (std::getline(ss, item, delim)) { 
  sprintf(combinedName,"%s%s%c",combinedName,item.c_str(),delim);          
  cout<<combinedName<<endl;
  struct stat st = {0};
  if (stat(combinedName,&st)==-1)
   { 
            #if REDHAT
                     mkdir(combinedName,0777);
            #else
                      CreateDirectory(combinedName,NULL);
            #endif
    }
 }
}
于 2016-04-14T13:28:01.513 に答える