0

I am passing through a directory and storing multiple file names into an array of string pointers. The problem is I have no idea how many I might be storing until I have completely passed through the directory. Here is how I have it currently setup.

char *dArr[512];
..
..
int i = 0;
while ((derent = readdir(directory)) != NULL) {
..
dArr[i] = derent->d_name;
i++;

The directory could return as little as 0-1 files or as much as 1000+ so is there a better approach for how to store these not knowing the size before hand?

kirax
  • 133
  • 1
  • 10
  • Try a Linked List: http://en.wikipedia.org/wiki/Linked_list – rullof Jan 25 '14 at 23:33
  • [nice detailed post about buffer sizes](http://stackoverflow.com/questions/2269063/buffer-growth-strategy) –  Jan 25 '14 at 23:34
  • So to answer your question: Without a library which provides you with dynamic growing data structures you have to do it on your own. C unfortunately does not provide anything like that per default :-( – Ingo Blackman Jan 25 '14 at 23:44

2 Answers2

0

Here is how I have implemented it some long time ago, although it solves the problem at hand within two "sweeps" (and not one, as you might have been aiming for in your question):

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

typedef struct
{
    int    fileCount; //The number of files in the current directory
    char*  fileIsDir; //An array of sub-dir flags (for each file)
    char** fileNames; //An array of names (for each file)
}
Directory;

void Open(Directory* directory)
{
    int    fileCount = 0;
    char*  fileIsDir = 0;
    char** fileNames = 0;

    int i;
    int handle;
    struct _finddata_t file;

    handle = _findfirst("*.*",&file);
    while (_findnext(handle,&file) == 0)
        fileCount++;
    _findclose(handle);

    fileIsDir = (char* )malloc(fileCount*sizeof(char ));
    fileNames = (char**)malloc(fileCount*sizeof(char*));

    handle = _findfirst("*.*",&file);
    for (i=0; i<fileCount; i++)
    {
        _findnext(handle,&file);
        fileIsDir[i] = (file.attrib&_A_SUBDIR)!=0;
        fileNames[i] = (char*)malloc(strlen(file.name)+1);
        strcpy(fileNames[i],file.name);
    }
    _findclose(handle);

    directory->fileCount = fileCount;
    directory->fileIsDir = fileIsDir;
    directory->fileNames = fileNames;
}

void Close(Directory* directory)
{
    int    fileCount = directory->fileCount;
    char*  fileIsDir = directory->fileIsDir;
    char** fileNames = directory->fileNames;

    int i;
    for (i=0; i<fileCount; i++)
        free(fileNames[i]);

    if (fileNames)
        free(fileNames);

    if (fileIsDir)
        free(fileIsDir);
}
barak manos
  • 29,648
  • 10
  • 62
  • 114
0

If you need a very simple dynamically growing structure here is also some more sample code:

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

struct mybuf {
    int bufsz;
    char *buf[1];
};

int test_alloc(int x)
{
    int i;
    struct mybuf *mb;
    // initially alloc buffer which can 
    // at least hold 32 (char *) pointers
    mb = (struct mybuf *)malloc(sizeof(*mb) + 32*sizeof(mb->buf[0]));
    mb->bufsz=32;

    for (i=0;i<x;i++) {
        if (i>=mb->bufsz) {
            // grow buffer size to i*1.5
            mb = realloc(mb,sizeof(*mb) + (i + i/2)*sizeof(mb->buf[0]) );
            mb->bufsz = i + i/2;
        }
        mb->buf[i] = (char *)"Hello World\n";
    }
    for (i=0;i<x;i++) {
        printf(mb->buf[i]);
    }

    free(mb);
}

int main()
{
    test_alloc(100);
    return 0;
}
Ingo Blackman
  • 991
  • 8
  • 13