Eccoti un esempio:

codice:
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>


#define ARRAY_SIZE(Array) \
   (sizeof(Array) / sizeof((Array)[0]))

#define BOOL short
#define TRUE 1
#define FALSE 0


/////////////////////////////////////////////////////////////

typedef struct
{
	int				nDepth;
	BOOL				fRecurse;
	char				szBuf[1024];
	int				nIndent;
	BOOL				fOk;
	BOOL				fIsDir;
	struct _finddata_t	FindData;
} DIRWALKDATA, *LPDIRWALKDATA;


BOOL IsChildDir (struct _finddata_t *lpFindData)
{
	BOOL bRet = (lpFindData->attrib & _A_SUBDIR) &&
				(lpFindData->name[0] != '.');
	
	return bRet;
}

BOOL FindNextChildDir (long hFindFile, struct _finddata_t *lpFindData)
{
	BOOL fFound = FALSE;

	int nFind;

	do
	{
		nFind = _findnext(hFindFile, lpFindData);
		if ( nFind == 0 )
			fFound = TRUE;
		else
			fFound = FALSE;
	} while ( fFound && !IsChildDir(lpFindData) );
	
	return(fFound);
}

long FindFirstChildDir (char * szPath, struct _finddata_t *lpFindData)
{
	BOOL fFound;

	long hFindFile = _findfirst(szPath, lpFindData);

	if (hFindFile != -1L)
	{
		fFound = IsChildDir(lpFindData);

		if (!fFound)
			fFound = FindNextChildDir(hFindFile, lpFindData);

		if (!fFound)
		{
			_findclose(hFindFile);
			hFindFile = -1L;
		}
	}
	return(hFindFile);
}

void DirWalkRecurse (LPDIRWALKDATA pDW)
{
	long hFind;
	pDW->nDepth++;
	
	pDW->nIndent = 3 * pDW->nDepth;
	sprintf(pDW->szBuf, "%*s", pDW->nIndent, "");

	_getcwd(&pDW->szBuf[pDW->nIndent],
			ARRAY_SIZE(pDW->szBuf) - pDW->nIndent);

	printf("pDW->szBuf -----> %s\n", pDW->szBuf);

	hFind = _findfirst("*.*", &pDW->FindData);
	pDW->fOk = ( hFind != -1L );

	while (pDW->fOk)
	{
		pDW->fIsDir = pDW->FindData.attrib & _A_SUBDIR;

		if (!pDW->fIsDir ||
			(!pDW->fRecurse && IsChildDir(&pDW->FindData)))
		{
			sprintf(pDW->szBuf,
					pDW->fIsDir ? "%*s[%s]" : "%*s%s",
					pDW->nIndent, "",
					pDW->FindData.name);

			printf("pDW->szBuf -----> %s\n", pDW->szBuf);
		}

		pDW->fOk = _findnext(hFind, &pDW->FindData) == 0 ? TRUE : FALSE;
	}
	
	if ( hFind != -1L )
		_findclose(hFind);

	if ( pDW->fRecurse )
	{
		hFind = FindFirstChildDir("*.*", &pDW->FindData);
		pDW->fOk = (hFind != -1L);
		
		while ( pDW->fOk )
		{
			if ( _chdir(pDW->FindData.name) == 0 )
			{
				DirWalkRecurse(pDW);
				_chdir("..");
			}
			pDW->fOk = FindNextChildDir(hFind, &pDW->FindData);
		}
		
		if ( hFind != -1L )
			_findclose(hFind);
	}
	
	pDW->nDepth--;
}

void DirWalk (char * pszRootPath, BOOL fRecurse)
{ 
	char szCurrDir[_MAX_DIR];
	DIRWALKDATA DW;

	_getcwd(szCurrDir, ARRAY_SIZE(szCurrDir));

	_chdir(pszRootPath);

	DW.nDepth = -1;

	DW.fRecurse = fRecurse;

	DirWalkRecurse(&DW);

	_chdir(szCurrDir);
}

int main(int argc, char* argv[])
{
	DirWalk("c:\\Tear", TRUE);

	return 0;
}
passando FALSE nel secondo parametro della funzione DirWalk, legge solo la directory passata nel primo parametro; con TRUE, invece, legge anche le sottodirectory.