Как я могу создать дерево каталогов в C++ / Linux?

Вы можете запретить любую предыдущую дату, немного используя JavaScript и атрибут min:

let [today] = new Date().toISOString().split("T");
document.querySelector("input").setAttribute("min", today);
<input name="cin" type ="date" class="form-control">
[1110 ]

Это обновится автоматически. Если вы не хотите разрешать любые проверки раньше, чем фиксированная дата (скажем, Новый год 2019), просто установите атрибут min вручную:

<input name="cin" type ="date" class="form-control" min="2019-01-01">
[1114 ]

104
задан Lipis 23 March 2009 в 20:10
поделиться

7 ответов

Вот функция C, которая может быть скомпилирована с компиляторами C++.

/*
@(#)File:           $RCSfile: mkpath.c,v $
@(#)Version:        $Revision: 1.13 $
@(#)Last changed:   $Date: 2012/07/15 00:40:37 $
@(#)Purpose:        Create all directories in path
@(#)Author:         J Leffler
@(#)Copyright:      (C) JLSS 1990-91,1997-98,2001,2005,2008,2012
*/

/*TABSTOP=4*/

#include "jlss.h"
#include "emalloc.h"

#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <string.h>
#include "sysstat.h"    /* Fix up for Windows - inc mode_t */

typedef struct stat Stat;

#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_mkpath_c[] = "@(#)$Id: mkpath.c,v 1.13 2012/07/15 00:40:37 jleffler Exp $";
#endif /* lint */

static int do_mkdir(const char *path, mode_t mode)
{
    Stat            st;
    int             status = 0;

    if (stat(path, &st) != 0)
    {
        /* Directory does not exist. EEXIST for race condition */
        if (mkdir(path, mode) != 0 && errno != EEXIST)
            status = -1;
    }
    else if (!S_ISDIR(st.st_mode))
    {
        errno = ENOTDIR;
        status = -1;
    }

    return(status);
}

/**
** mkpath - ensure all directories in path exist
** Algorithm takes the pessimistic view and works top-down to ensure
** each directory in path exists, rather than optimistically creating
** the last element and working backwards.
*/
int mkpath(const char *path, mode_t mode)
{
    char           *pp;
    char           *sp;
    int             status;
    char           *copypath = STRDUP(path);

    status = 0;
    pp = copypath;
    while (status == 0 && (sp = strchr(pp, '/')) != 0)
    {
        if (sp != pp)
        {
            /* Neither root nor double slash in path */
            *sp = '\0';
            status = do_mkdir(copypath, mode);
            *sp = '/';
        }
        pp = sp + 1;
    }
    if (status == 0)
        status = do_mkdir(path, mode);
    FREE(copypath);
    return (status);
}

#ifdef TEST

#include <stdio.h>

/*
** Stress test with parallel running of mkpath() function.
** Before the EEXIST test, code would fail.
** With the EEXIST test, code does not fail.
**
** Test shell script
** PREFIX=mkpath.$$
** NAME=./$PREFIX/sa/32/ad/13/23/13/12/13/sd/ds/ww/qq/ss/dd/zz/xx/dd/rr/ff/ff/ss/ss/ss/ss/ss/ss/ss/ss
** : ${MKPATH:=mkpath}
** ./$MKPATH $NAME &
** [...repeat a dozen times or so...]
** ./$MKPATH $NAME &
** wait
** rm -fr ./$PREFIX/
*/

int main(int argc, char **argv)
{
    int             i;

    for (i = 1; i < argc; i++)
    {
        for (int j = 0; j < 20; j++)
        {
            if (fork() == 0)
            {
                int rc = mkpath(argv[i], 0777);
                if (rc != 0)
                    fprintf(stderr, "%d: failed to create (%d: %s): %s\n",
                            (int)getpid(), errno, strerror(errno), argv[i]);
                exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
            }
        }
        int status;
        int fail = 0;
        while (wait(&status) != -1)
        {
            if (WEXITSTATUS(status) != 0)
                fail = 1;
        }
        if (fail == 0)
            printf("created: %s\n", argv[i]);
    }
    return(0);
}

#endif /* TEST */

Макросы STRDUP() и FREE() версии проверки ошибок strdup() и free(), объявленный в emalloc.h (и реализованный в emalloc.c и estrdup.c). "sysstat.h" заголовок имеет дело с поврежденными версиями <sys/stat.h> и может быть заменен <sys/stat.h> в современных системах Unix (но было много проблем назад в 1990). И "jlss.h" объявляет mkpath().

Изменение между (предыдущим) v1.12 и v1.13 (выше) является тестом для EEXIST в do_mkdir(). На это указал по мере необходимости Переключатель — спасибо, Переключатель. Тестовый код был обновлен и воспроизвел проблему на MacBook Pro (Intel Core i7 на 2.3 ГГц, под управлением Mac OS X 10.7.4), и предполагает, что проблема решена в пересмотре (но тестирование может только показать присутствие ошибок, никогда их отсутствие).

(Вам настоящим дают разрешение использовать этот код для любой цели с атрибуцией.)

58
ответ дан Community 24 November 2019 в 04:03
поделиться

Другие получили Вас правильный ответ, но я думал, что продемонстрирую другую аккуратную вещь, которую можно сделать:

mkdir -p /tmp/a/{b,c}/d

Создаст следующие пути:

/tmp/a/b/d
/tmp/a/c/d

Фигурные скобки позволяют Вам создавать несколько каталогов сразу на том же уровне иерархии, тогда как -p средства опции "создают родительские каталоги по мере необходимости".

-2
ответ дан rmeador 24 November 2019 в 04:03
поделиться
mkdir -p /dir/to/the/file

touch /dir/to/the/file/thefile.ending
0
ответ дан Tim Cooper 24 November 2019 в 04:03
поделиться

Вы сказали "C++", но все здесь, кажется, думают "оболочка Bash".

Проверьте исходный код гну mkdir; затем Вы видите, как реализовать команды оболочки в C++.

7
ответ дан Jason Cohen 24 November 2019 в 04:03
поделиться
#include <sys/types.h>
#include <sys/stat.h>

int status;
...
status = mkdir("/tmp/a/b/c", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

Отсюда. Вам, вероятно, придется сделать отдельный mkdirs для/tmp,/tmp/a,/tmp/a/b/и затем/tmp/a/b/c, потому что нет эквивалента флага-p в API C. Убедитесь и проигнорируйте EEXISTS errno при выполнении верхних уровня.

23
ответ дан Paul Tomblin 24 November 2019 в 04:03
поделиться

Легкий с повышением. Файловая система: create_directories

#include <boost/filesystem.hpp>
//...
boost::filesystem::create_directories("/tmp/a/b/c");

Возвраты: true если новый каталог был создан, иначе false.

154
ответ дан chappjc 24 November 2019 в 04:03
поделиться
system("mkdir -p /tmp/a/b/c")

самый короткий способ, которым я могу думать (с точки зрения длины кода, не обязательно время выполнения).

Это не является межплатформенным, но будет работать в соответствии с Linux.

37
ответ дан einpoklum - reinstate Monica 24 November 2019 в 04:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: