简体   繁体   中英

save file listing into array or something else C

I have this function

void file_listing(){
    DIR *dp;
    struct stat fileStat;
    struct dirent *ep;
    int file=0;
    dp = opendir ("./");

    if (dp != NULL){
        while ((ep = readdir(dp))){
            char *c = ep->d_name;
            char d = *c; /* first char */
            if((file=open(ep->d_name,O_RDONLY)) < -1){ 
                perror("Errore apertura file");
            }
            if(fstat(file,&fileStat)){ /*file info */
                perror("Errore funzione fstat");
            }
            if(S_ISDIR(fileStat.st_mode)){ /* directory NOT listed */
                continue;
            }
            else{
                if(d != '.'){ /* if filename DOESN'T start with . will be listed */
                    "save into someting" (ep->d_name);
                }
                else{
                    continue; /* altrimenti non lo listo */
                }
            }
        }
        (void) closedir (dp);
    }
    else{
        perror ("Impossibile aprire la directory");
        return 1;
    }
}

I want to save into an array or a struct or a list or something else the result of file listing but i don't know how to do it.
Thanks in advance!

Here is a sample function that stores the file listing in array and returns the number of entries:

#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <malloc.h>

size_t file_list(const char *path, char ***ls) {
    size_t count = 0;
    size_t length = 0;
    DIR *dp = NULL;
    struct dirent *ep = NULL;

    dp = opendir(path);
    if(NULL == dp) {
        fprintf(stderr, "no such directory: '%s'", path);
        return 0;
    }

    *ls = NULL;
    ep = readdir(dp);
    while(NULL != ep){
        count++;
        ep = readdir(dp);
    }

    rewinddir(dp);
    *ls = calloc(count, sizeof(char *));

    count = 0;
    ep = readdir(dp);
    while(NULL != ep){
        (*ls)[count++] = strdup(ep->d_name);
        ep = readdir(dp);
    }

    closedir(dp);
    return count;
}

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

    char **files;
    size_t count;
    int i;

    count = file_list("/home/rgerganov", &files);
    for (i = 0; i < count; i++) {
        printf("%s\n", files[i]);
    }
}

Note that I iterate twice over the directory - first time to get the files count and second time to save the results. This won't work correctly if you add/remove files in the directory while this is being executed.

An other example, more cleaner but not thread safe because readdir() is not:

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static void *realloc_or_free(void *ptr, size_t size) {
  void *tmp = realloc(ptr, size);
  if (tmp == NULL) {
    free(ptr);
  }
  return tmp;
}

static int get_dirent_dir(char const *path, struct dirent **result,
                          size_t *size) {
  DIR *dir = opendir(path);
  if (dir == NULL) {
    closedir(dir);
    return -1;
  }

  struct dirent *array = NULL;
  size_t i = 0;
  size_t used = 0;
  struct dirent *dirent;
  while ((dirent = readdir(dir)) != NULL) {
    if (used == i) {
      i += 42; // why not?
      array = realloc_or_free(array, sizeof *array * i);
      if (array == NULL) {
        closedir(dir);
        return -1;
      }
    }

    array[used++] = *dirent;
  }

  struct dirent *tmp = realloc(array, sizeof *array * used);
  if (tmp != NULL) {
    array = tmp;
  }

  *result = array;
  *size = used;

  closedir(dir);

  return 0;
}

static int cmp_dirent_aux(struct dirent const *a, struct dirent const *b) {
  return strcmp(a->d_name, b->d_name);
}

static int cmp_dirent(void const *a, void const *b) {
  return cmp_dirent_aux(a, b);
}

int main(void) {
  struct dirent *result;
  size_t size;
  if (get_dirent_dir(".", &result, &size) != 0) {
    perror("get_file_dir()");
  }

  qsort(result, size, sizeof *result, &cmp_dirent);

  for (size_t i = 0; i < size; i++) {
    printf("%s\n", result[i].d_name);
  }

  free(result);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM