我发现了很多递归创建目录的例子,但不是我要找的那个。
这是规格
给定输入
- \\服务器\共享\aa\bb\cc
- c:\aa\bb\cc
使用帮助 API
CreateDirectory (char * path)
returns true, if successful
else
FALSE
条件:不应该有任何解析来区分路径是本地还是服务器共享。
用 C 或 C++ 编写例程
我认为这很容易......这里有一个适用于每个 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);
问候,
这可能正是您想要的。它不会尝试进行任何解析来区分路径是本地还是服务器共享。
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;
}
该算法非常简单,只需递归传递更高级别目录的字符串,同时创建当前级别目录失败,直到成功或没有更高级别。当内部调用成功返回时,创建当前调用。此方法不解析确定本地或服务器它自己,它是根据 CreateDirectory。在 WINAPI 中,当路径达到该级别时,CreateDirectory 将永远不允许您创建“c:”或“\”,该方法很快就会使用 path="" 调用它,这也失败了。这就是微软这样定义文件共享命名规则的原因,是为了兼容 DOS 路径规则并简化编码工作。
使用MakeSureDirectoryPathExists () 怎么样?
完全骇人听闻且不安全,而且您实际上不想在生产代码中做任何事情,但是...
警告:这里是在浏览器中输入的代码:
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;
}
不解析服务器名称的路径名的要求很有趣,因为它似乎承认需要解析/
。
也许这个想法是为了避免为主机和挂载点的潜在复杂语法构建骇人听闻的表达式,这可能在某些系统上具有精心编码的凭据。
如果这是家庭作业,我可能会放弃您应该考虑的算法,但我想到满足这些要求的一种方法是通过尝试 mkdir 完整路径名来开始尝试。如果失败,剪掉最后一个目录,然后重试,如果失败,剪掉另一个目录,然后重试......最终你应该到达根目录而不需要了解服务器语法,然后你需要开始添加路径名组件返回并一一制作子目录。
只需从根目录开始遍历路径中的每个目录级别,尝试创建下一个级别。
如果任何 CreateDirectory 调用失败,那么您可以提前退出,如果您在没有失败的情况下到达路径的尽头,您就是成功的。
这是假设在已经存在的路径上调用 CreateDirectory 没有不良影响。
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()
);
}
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
}
}
}