рекурсивное сканирование папки в C++

Я только что попробовал это, и это сработало:

<input asp-for="filter.type[i].IsEnabled"/>

без флажка, а затем соответствующее логическое значение в модели со скрытым идентификатором и именем.

13
задан Jørgen R 19 December 2014 в 22:48
поделиться

6 ответов

См. man ftw для простого "обхода файлового дерева". В этом примере я также использовал fnmatch .

#include <ftw.h>
#include <fnmatch.h>

static const char *filters[] = {
    "*.jpg", "*.jpeg", "*.gif", "*.png"
};

static int callback(const char *fpath, const struct stat *sb, int typeflag) {
    /* if it's a file */
    if (typeflag == FTW_F) {
        int i;
        /* for each filter, */
        for (i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
            /* if the filename matches the filter, */
            if (fnmatch(filters[i], fpath, FNM_CASEFOLD) == 0) {
                /* do something */
                printf("found image: %s\n", fpath);
                break;
            }
        }
    }

    /* tell ftw to continue */
    return 0;
}

int main() {
    ftw(".", callback, 16);
}

(Даже не проверял компиляцию, но вы поняли идею.)

Это намного проще, чем иметь дело с DIRENT и рекурсивный обход самостоятельно.


Для большего контроля над обходом существует также fts . В этом примере точечные файлы (файлы и каталоги с именами, начинающимися с ".") Пропускаются, если явно не переданы программе в качестве отправной точки.

#include <fts.h>
#include <string.h>

int main(int argc, char **argv) {
    char *dot[] = {".", 0};
    char **paths = argc > 1 ? argv + 1 : dot;

    FTS *tree = fts_open(paths, FTS_NOCHDIR, 0);
    if (!tree) {
        perror("fts_open");
        return 1;
    }

    FTSENT *node;
    while ((node = fts_read(tree))) {
        if (node->fts_level > 0 && node->fts_name[0] == '.')
            fts_set(tree, node, FTS_SKIP);
        else if (node->fts_info & FTS_F) {
            printf("got file named %s at depth %d, "
                "accessible via %s from the current directory "
                "or via %s from the original starting directory\n",
                node->fts_name, node->fts_level,
                node->fts_accpath, node->fts_path);
            /* if fts_open is not given FTS_NOCHDIR,
             * fts may change the program's current working directory */
        }
    }
    if (errno) {
        perror("fts_read");
        return 1;
    }

    if (fts_close(tree)) {
        perror("fts_close");
        return 1;
    }

    return 0;
}

Опять же, он не тестировался ни при компиляции, ни при запуске, но я думал, что упомяну об этом.

30
ответ дан 1 December 2019 в 18:55
поделиться

Boost.Filesystem позволяет вам это делать. Ознакомьтесь с документами !

РЕДАКТИРОВАТЬ:
Если вы используете Linux и не хотите использовать Boost, вам придется использовать собственные функции C. На этой странице показано множество примеров того, как это сделать.

6
ответ дан 1 December 2019 в 18:55
поделиться

Вы захотите использовать функции каталогов, объявленные в dirent.h. Эта страница википедии описывает их и включает примеры кода. Для вашего приложения, как только вы определили каталог, вы захотите снова рекурсивно вызвать функцию обработки для обработки содержимого каталога.

1
ответ дан 1 December 2019 в 18:55
поделиться

Вы также можете использовать glob / globfree.

1
ответ дан 1 December 2019 в 18:55
поделиться

Я думаю, что если вы можете использовать Qt / Embedded, есть классы QDir и QFileInfo, которые может вам помочь, хотя это зависит от того, можете ли вы использовать Qt. Вопрос в том, какой API предоставляет ваша система.

0
ответ дан 1 December 2019 в 18:55
поделиться

Я олдскульный, нет ftw () для меня! Это грубо (я давно не занимался прямым программированием на C), и многие вещи жестко запрограммированы, и я, вероятно, испортил свои вычисления длины для функций strnc * (), но вы поняли идею. Аналогичный пример есть в K&R btw.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <dirent.h>

void listdir(char* dirname, int lvl);

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

  if (argc != 2) {
    fprintf(stderr, "Incorrect usage!\n");
    exit(-1);
  }
  listdir(argv[1], 0);


  return 0;
}

void listdir(char* dirname, int lvl)
{

  int i;
  DIR* d_fh;
  struct dirent* entry;
  char longest_name[4096];

  while( (d_fh = opendir(dirname)) == NULL) {
    fprintf(stderr, "Couldn't open directory: %s\n", dirname);
    exit(-1);
  }

  while((entry=readdir(d_fh)) != NULL) {

    /* Don't descend up the tree or include the current directory */
    if(strncmp(entry->d_name, "..", 2) != 0 &&
       strncmp(entry->d_name, ".", 1) != 0) {

      /* If it's a directory print it's name and recurse into it */
      if (entry->d_type == DT_DIR) {
        for(i=0; i < 2*lvl; i++) {
          printf(" ");
        }
        printf("%s (d)\n", entry->d_name);

        /* Prepend the current directory and recurse */
        strncpy(longest_name, dirname, 4095);
        strncat(longest_name, "/", 4095);
        strncat(longest_name, entry->d_name, 4095);
        listdir(longest_name, lvl+1);
      }
      else {

        /* Print some leading space depending on the directory level */
        for(i=0; i < 2*lvl; i++) {
          printf(" ");
        }
        printf("%s\n", entry->d_name);
      }
    }
  }

  closedir(d_fh);

  return;
}
2
ответ дан 1 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

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