Reading directories recursively

This is a discussion on Reading directories recursively within the C Programming forums, part of the General Programming Boards category; Ok, my mission that I would like to accomplish is to set my program wild on a certain directory. Its ...

  1. #1
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    398

    Reading directories recursively

    Ok, my mission that I would like to accomplish is to set my program wild on a certain directory. Its mission is to find every mp3 file, rename it to my liking, and organize them(I can handle this myself). I figured the easiest way would be to build an array of all of the directories and subdirectories, and once I finished moving the files in one, move to the next one.

    Of course I have some big issues, but I really need some ideas. In my opinion the way I am doing it probably sucks. Here is the code I have been messing with, and it currently does not compile. But hopefully it can show you my idea.

    I would like to take any suggestions about changing my approach completely. It seems to me like I am making a fairly simple thing hard.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <windows.h>
    
    char* basedir = "C:\\Music\\*";
    
    int main (void)
    {
    	WIN32_FIND_DATA f;
    	HANDLE h = FindFirstFile(basedir, &f);
    	char* dirs[1000];
    	char* tempdir;
    	int i = 0;
    	int j = 0;
    	int k = 0;
    
    	while (h != INVALID_HANDLE_VALUE)
    	{
    		while (FindNextFile(h, &f))
    		{
    
    			if (f.dwFileAttributes == 16)
    			{
    				dirs[j] = f.cFileName;
    				j++;
    			}
    			else
    			{
    				//will eventually move the file
    			}
    		} 
    
    		if (j > k)
    		{
    			tempdir = strcat(basedir, dirs[k]);
    			h = FindFirstFile(tempdir, &f);
    			k++;
    		}
    
    	}
    
    return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,845
    There's a win32 tree walker in the FAQ.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    398
    I tried to find the Win32 tree walker and had trouble finding it. A link could be nice.

    Anyway, here is my code again. Not quite working correctly yet but doing better than before. If anyone would help, I would much appreciate it. Here once again is the rundown I am trying to acheive.

    Give my program a directory, and fill an array will all paths. example:
    Code:
    dirs[0] = "C:\";
    dirs[1] = "C:\Music\";
    dirs[2] = "C:\Videos\";
    dirs[3] = "C:\Music\Marley\";
    etc...
    Here is what I am working with:
    Code:
    #define _CRT_SECURE_NO_DEPRECATE 1
    
    #include <stdio.h>
    #include <string.h>
    #include <windows.h>
    
    LPTSTR extensn = "\\";
    LPTSTR asteris = "*";
    
    int main (void)
    {
    	WIN32_FIND_DATA f;
    	DWORD buffSize = MAX_PATH;
    	LPTSTR lpszBuffer = (LPTSTR)malloc(buffSize *sizeof(char));
    	LPTSTR tempdir = (LPTSTR)malloc(buffSize *sizeof(char));
    	LPTSTR basedir = (LPTSTR)malloc(buffSize *sizeof(char));
    	LPTSTR dirs[1000];
    	HANDLE h;
    	int i = 0;
    	int j = 0;
    	int k = 0;
    	sprintf(basedir, "&#37;s", "C:\\Music");
    	sprintf(lpszBuffer, "%s%s%s", basedir, extensn, asteris);
    	h = FindFirstFile(lpszBuffer, &f);
    
    
    	while (h != INVALID_HANDLE_VALUE)
    	{
    		while (FindNextFile(h, &f))
    		{
    			if (f.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
    			{
    				if (strcmp(f.cFileName, "..") != FALSE)
    				{
    					sprintf(lpszBuffer, "%s%s%s", basedir, extensn, f.cFileName);
    					dirs[j] = lpszBuffer;
    					printf("ADDED %s\t%d\n", dirs[j], j);
    					j++;
    				}
    			}
    			else
    			{
    				printf("FILE FOUND!\n");
    				//Will try to move it later
    			}
    		} 
    
    		if (j > k)
    		{
    			sprintf(lpszBuffer, "%s%s%s", lpszBuffer, extensn, asteris);		
    			h = FindFirstFile(lpszBuffer, &f);
    			k++;
    		}
    
    	}
            //Strange thing here, the array values seem to be different than what I set them to above
    	for (i = 0; i < j; i++)
    		printf("%s\n", dirs[j]);
    
    return 0;
    }

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The standard idiom would be to use dir[i], not j.

    Code:
            //Strange thing here, the array values seem to be different than what I set them to above
    	for (i = 0; i < j; i++)
    		printf("%s\n", dirs[j]);
    See if that doesn't help.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,020
    Avoid pointer typedefs such as LPTSTR. Do you know what it is?
    Your "dirs" array is just an array of pointers, each one pointing to lpszBuffer. Which means that every time your lpszBuffer changes, so does dirs[x]. You must use a real buffer and copy the string over via strcpy.
    And you're far better off just using normal, fixed-size arrays instead of malloc here. You are not freeing the malloced data and you are not calling CloseHandle either which you must do after the FindFirstFile call.
    Also beware that you can get a buffer overrun in lpszBuffer because it's just MAX_PATH characters. If the directory you found is MAX_PATH, then you will copy MAX_PATH + 2 bytes which means buffer overrun.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    Code:
    sprintf(basedir, "&#37;s", "C:\\Music");
    By the way, that's the same thing as
    Code:
    strcpy(basedir, "C:\\Music");
    except that strcpy() is probably more efficient.

    Also note that sizeof(char) is always 1, so you don't have to include it.

    Lastly, malloc() is in <stdlib.h>, so you should include that.

    Code:
    			if (f.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
    			{
    				if (strcmp(f.cFileName, "..") != FALSE)
    				{
    					sprintf(lpszBuffer, "%s%s%s", basedir, extensn, f.cFileName);
    					dirs[j] = lpszBuffer;
    					printf("ADDED %s\t%d\n", dirs[j], j);
    					j++;
    				}
    			}
    On Linux, at least, I think you have to ignore "." as well as "..". Perhaps this doesn't apply to Windows.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,020
    Oh right. You have to ignore "." in Windows, too.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Resetting a ifstream object after reading the whole file
    By Zeeshan in forum C++ Programming
    Replies: 5
    Last Post: 03-31-2008, 09:03 AM
  2. Replies: 2
    Last Post: 01-28-2008, 03:07 AM
  3. help with reading from stream
    By movl0x1 in forum C Programming
    Replies: 7
    Last Post: 05-31-2007, 11:36 PM
  4. question about reading files in
    By smd in forum C++ Programming
    Replies: 11
    Last Post: 08-25-2003, 08:40 PM
  5. problems reading data into an array and printing output
    By serino78 in forum C Programming
    Replies: 4
    Last Post: 04-28-2003, 09:39 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21