Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 7, 2013, 12:50 PM   #1
farmerdoug
macrumors 6502a
 
Join Date: Sep 2008
getting a list of files from a directory

I am writing a routine to return a list of files in a directory in C. The routine takes the directory name and a maximum value for the number of files. I want it to be portable. And I'd like to get rid of the warning that **file_list is not initialized. Comments and help. thanks.

Code:
#include <stdio.h>
#include <stdlib.h>
#define num_files 100
void get_file_list( char * dir, char ** file_list);
int main(int argc, const char * argv[])
{

	char **file_list, *dir;
	
	dir = (char *) calloc(25, sizeof(char));
	file_list = (char **) calloc(25, sizeof(char*));
	  
	get_file_list(dir, file_list);
	
	
	return 0;
}


void get_file_list( char * dir, char ** file_list)
{

	int i;
	file_list = (char **) calloc(num_files, sizeof(char*));
	for (i = 0; i < num_files; i++)
		file_list[i]  = (char *) calloc(25, sizeof(char));
		
	//code


}
farmerdoug is offline   0 Reply With Quote
Old Apr 7, 2013, 09:17 PM   #2
lloyddean
macrumors 6502a
 
Join Date: May 2009
Location: Des Moines, WA
Are you asking for code to read a directory?

I'm sure you'll find plenty of examples along the lines of ...

Code:
void listdir(char* dir)
{
    struct dirent*  pdirent;
    DIR*                pdir        = opendir(dir);
    if ( pdir )
    {
        while ((pdirent = readdir(pdir)) != NULL)
        {
            if ( ! strcmp(pdirent->d_name, ".") || ! strcmp(pdirent->d_name, "..") )
            {
                /* don't bother showing parent or current directory */
                continue;
            }

            printf("%s/%s\n", dir, pdirent->d_name);
        }

        closedir(pdir);

        return;
    }

    fprintf(stderr, "listdir: can't open %s\n", dir);
}
... that you can adapt to your purposes.
lloyddean is offline   0 Reply With Quote
Old Apr 7, 2013, 09:35 PM   #3
farmerdoug
Thread Starter
macrumors 6502a
 
Join Date: Sep 2008
Actually, I was more interested in how I should allocate memory and pass pointers back and forth. The code you sent, which is actually very helpful because it teaches me about calls I was aware of, doesn't help me see how best to that. I need a list of files in the directory.
farmerdoug is offline   0 Reply With Quote
Old Apr 7, 2013, 11:25 PM   #4
lloyddean
macrumors 6502a
 
Join Date: May 2009
Location: Des Moines, WA
Well without much thought and the restriction that the directory being traversed is static and will not change during the running of the program -

Code:
int get_file_list(char* pszDirectoryName, char** ppsz)
{
    int             entries_count   = 0;

    struct dirent*  pdirent;
    DIR*            pdir;

    pdir = opendir(pszDirectoryName);
    if ( pdir )
    {
        while ( (pdirent = readdir(pdir)) )
        {
            if ( ! strcmp(pdirent->d_name, ".") || ! strcmp(pdirent->d_name, "..") )
            {
                /* don't bother show parent or current directory */
                continue;
            }

            if ( ppsz )
            {
                char* psz = (char*)calloc(strlen(pdirent->d_name) + 1, sizeof(char));
                strcpy(psz, pdirent->d_name);

                ppsz[entries_count] = psz;
            }

            entries_count++;
        }

        closedir(pdir);

        return entries_count;
    }

    return 0;
}

int main(void)
{
    int entries_count   = get_file_list("/", NULL);
    char** ppsz         = (char**)calloc(entries_count, sizeof(char*));
    entries_count       = get_file_list("/", ppsz);

    for (int i = entries_count; i--; )
    {
        printf("%s\n", ppsz[i]);

        free((void*)ppsz[i]);
    }

    free((void*)ppsz);

    return EXIT_SUCCESS;
}

Last edited by lloyddean; Apr 8, 2013 at 01:33 AM.
lloyddean is offline   0 Reply With Quote
Old Apr 8, 2013, 08:18 AM   #5
robvas
macrumors 68000
 
Join Date: Mar 2009
Location: USA
Doug:

I'm going to suggest again you use a language like Python or Ruby for your tasks. You can do something like this in a one-liner:
Code:
 dir_contents = Dir.entries("/absolute/path/to/directory")
robvas is offline   0 Reply With Quote
Old Apr 8, 2013, 11:19 AM   #6
Senor Cuete
macrumors regular
 
Join Date: Nov 2011
free()

You need to balance your calls to calloc() with free() or you will have memory leaks.
Senor Cuete is offline   0 Reply With Quote
Old Apr 8, 2013, 11:48 AM   #7
farmerdoug
Thread Starter
macrumors 6502a
 
Join Date: Sep 2008
Leaks.
In the main code, if I call the routine more than once. Yes. Thanks.
farmerdoug is offline   0 Reply With Quote
Old Apr 8, 2013, 12:07 PM   #8
lloyddean
macrumors 6502a
 
Join Date: May 2009
Location: Des Moines, WA
Quote:
Originally Posted by Senor Cuete View Post
You need to balance your calls to calloc() with free() or you will have memory leaks.
As I said I threw it together without much thought.

As well you're presuming my motive is to provide Doug with well written software and I can assure you it's not. I'm simply trying to get him to "Think Different" not do his work for him.
lloyddean is offline   0 Reply With Quote
Old Apr 8, 2013, 12:19 PM   #9
farmerdoug
Thread Starter
macrumors 6502a
 
Join Date: Sep 2008
Lloyd,
I've really been trying to clean up my act. That's why the orignal question was more about passing pointers in the proper manner than writing the read directory code, as I said.
farmerdoug is offline   0 Reply With Quote
Old Apr 8, 2013, 02:13 PM   #10
lloyddean
macrumors 6502a
 
Join Date: May 2009
Location: Des Moines, WA
The same thing done in C++ mixed with C.

Note the use of STL containers 'string' and 'vector' handling all memory allocation/deallocation for you!

Again threw it together with little thought other than showing the utility of C++ and the STL to simplify programming tasks such as yours.

Code:
#include <cstdlib>

#include <iostream>
#include <string>
#include <vector>

#include <dirent.h>

typedef std::vector<std::string>            svec_t;
typedef std::vector<std::string>::iterator  svec_itr;

void GetDirContnets(const char* pszDirectoryName, svec_t& svec)
{
    DIR* pdir = opendir(pszDirectoryName);
    if ( pdir )
    {
        struct dirent*  pdirent;

        while ( (pdirent = readdir(pdir)) )
        {
            if ( strcmp(pdirent->d_name, ".") && strcmp(pdirent->d_name, "..") )
            {
                svec.push_back(pdirent->d_name);
            }
        }

        closedir(pdir);
    }
}

int main(void)
{
    svec_t  svec;
    GetDirContnets("/", svec);

    for ( svec_itr itr = svec.begin(); itr != svec.end(); itr++ )
    {
        cout << *itr << "\n";
    }

    return EXIT_SUCCESS;
}

Last edited by lloyddean; Apr 9, 2013 at 12:45 AM.
lloyddean is offline   0 Reply With Quote
Old Apr 8, 2013, 03:37 PM   #11
subsonix
macrumors 68040
 
Join Date: Feb 2008
Assuming the question is about resource management. It would probably be better to do all allocation in your get_* function as opposed to doing it in two places. Just return a new list or NULL on failure. Also, since you are allocating for each directory entry string manually, there is no need to restrict yourself to 25 characters, allocate strlen +1 or use strdup.

Finally create a corresponding free_* function to free the entire list in one go.
subsonix is offline   0 Reply With Quote
Old Apr 8, 2013, 04:02 PM   #12
lloyddean
macrumors 6502a
 
Join Date: May 2009
Location: Des Moines, WA
I'm simply trying to get him to reconsider his contortionist memory allocation and parameter passing monstrosities as being complex, mind numbing and totally unnecessary.
lloyddean is offline   0 Reply With Quote
Old Apr 8, 2013, 06:03 PM   #13
Senor Cuete
macrumors regular
 
Join Date: Nov 2011
Quote:
Originally Posted by farmerdoug View Post
Leaks.
In the main code, if I call the routine more than once. Yes. Thanks.
Even once.
Senor Cuete is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Mavericks - extremely slow to list files when selecting files in finder and Safari iosuser OS X Mavericks (10.9) 33 Aug 29, 2014 04:40 AM
Would you like access to the iOS file directory to save, move, edit files? Yes or no? Lloydbm41 iOS 7 54 Feb 23, 2014 12:12 PM
Portable Home Directory - Files Keep Appearing phenostar Mac OS X Server, Xserve, and Networking 0 Oct 27, 2013 07:29 PM
Copy files into sub-directory in list view theEconomist Mac Basics and Help 0 Jul 4, 2013 05:20 AM
Does adding a new account create files outside of it's home directory? rawdawg OS X 10.8 Mountain Lion 7 Nov 15, 2012 11:07 PM

Forum Jump

All times are GMT -5. The time now is 02:05 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC