我正在完成 cs50x(哈佛 cs50 的 edX(免费)版本)课程,并试图变得有点棘手/懒惰/测试自己。
我正在尝试使用 C 程序来创建 pset 所需的所有目录。
我在网上查看,发现
<sys/stat.h>
包含 mkdir()
函数,因此尝试创建一些嵌套循环来创建所有必要的文件夹,方法是执行类似于 mkdir {pset1,pset1/{standard,hacker},pset2,pset2{standard...
的操作,为我提供如下目录结构:
pset1/Standard
pset1/Hacker
pset2/Standard
等等...
我想出了这个:
#include <cs50.h>
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, string argv[])
{
for(int i = 1; i <=8; i++)
{
string dir = argv[1];
sprintf(dir,"%s%i", argv[1], i);
mkdir(dir, 0777);
for(int j = 0; j<2; j++)
{
string subDir[] = {"Standard","Hacker"};
sprintf(dir,"%s%i/%s", argv[1], i, subDir[j]);
mkdir(dir, 0777);
}
}
}
但是,程序只创建
pset1
并完成,没有子文件夹,没有pset2
等
要创建完整路径,您可以像这样递归调用
mkdir()
:
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
int mkdirr(const char * path, const mode_t mode, const int fail_on_exist)
{
int result = 0;
char * dir = NULL;
do
{
if (NULL == path)
{
errno = EINVAL;
result = -1;
break;
}
if ((dir = strrchr(path, '/')))
{
*dir = '\0';
result = mkdirr(path, mode, fail_on_exist);
*dir = '/';
if (result)
{
break;
}
}
if (strlen(path))
{
if ((result = mkdir(path, mode)))
{
char s[PATH_MAX];
sprintf(s, "mkdir() failed for '%s'", path);
perror(s);
if ((EEXIST == result) && (0 == fail_on_exist))
{
result = 0;
}
else
{
break;
}
}
}
} while (0);
return result;
}
然后像这样调用
mkdirr()
;
int main(void)
{
char p[] = "test/1/2/3";
if (-1 == mkdirr(p, 0777, 0))
{
perror("mkdirr() failed()");
}
return 0;
}
是的,你很懒,因为你似乎对 C 的了解很少,但却尝试用它来编程。 :)
C 不是 Python,没有字符串插值/格式化运算符。你必须调用一个函数,特别是
snprintf()
。阅读该手册页。
此外,您无法通过一次调用
mkdir()
创建一堆嵌套目录。阅读手册页。
要创建嵌套目录,您要么必须构建每个目录的绝对路径(即每次连续调用
mkdir()
时,路径都会比前一次更长),或实际上输入每个目录创建它,然后从那里开始。
/*
* Creates nested directory
* len -> path string length
* path -> directory to be created
* example path-> /usr/local/apat/10/test/ , in this case it will check if all
* diretories like /usr, /usr/local, /usr/local/apat, /usr/local/apat/10 and
* /usr/local/apat/10/test are present or not. If not present then created.
*/
bool create_nested_directories(char *path, int len)
{
int index = 1;
bool ret = false;
struct stat stats;
bool checkfordir = true;
char *lpath = (char *)malloc(len+1);
if(path == NULL) goto end;
if(len <= 0) goto end;
strcpy(lpath, path);
while(index < len)
{
if(lpath[index] == '/')
{
lpath[index] = 0x0;
if(checkfordir == true)
{
if(!(stat(lpath, &stats) == 0 && S_ISDIR(stats.st_mode)))
{
checkfordir = false; //once check retruns false, always will be flase for res of the lpath
mkdir(lpath, 0755);
}
}
else
{
mkdir(lpath, 0755);
}
lpath[index] = '/';
}
index++;
}
end:
free(lpath);
return ret;
}