您的位置:首页 > 编程语言 > C语言/C++

C语言 递归地删除一个指定目录下所有指定类型的文件

2012-02-23 22:27 896 查看
/*
** del.c
** mayadong7349 2012-02-23
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <direct.h>
#include <io.h>

#ifndef MAX_PATH
#define MAX_PATH 260
#endif

#define STRCAT(buf, buf_size, str)  \
do { \
if ( ( buf_size - 1 - strlen(buf) ) <  strlen(str) ) { \
errno = ENOMEM; \
return; \
} else { \
strcat(buf, str); \
} \
} while(0)

typedef struct _finddata_t FileInfo;

FILE *fplog;

void dump(const char *ptype)/* delete the types of file you specified in current working directory */
{
FileInfo file_info   = {0U};
long     file_handle = -1L;

assert(ptype != NULL);
    assert( 0 != strcmp(ptype, "*.*") );
    assert( 0 != strcmp(ptype, "*") );

 if ( -1L == ( file_handle = _findfirst(ptype, &file_info) ) ) {
return;
} else {
do {
#ifdef NDEBUG
remove(file_info.name);
#endif
fprintf(fplog, "\t>>> delete %s\n", file_info.name);
} while ( 0 == _findnext(file_handle, &file_info) );
_findclose(file_handle);
}
}

void recurse_path(const char *path, const char *ptype)
{
char     path_buf[MAX_PATH] = "\0";
FileInfo file_info          = { 0U };
long     file_handle        = -1L;

assert(ptype != NULL);

STRCAT(path_buf, MAX_PATH, path);
STRCAT(path_buf, MAX_PATH,"\\*" );

if ( -1L == ( file_handle = _findfirst(path_buf, &file_info) ) ) {
return;
} else  {
do {
if (file_info.attrib & _A_SUBDIR) {/* a subdirectory */
if ( 0 == strcmp(file_info.name, "..") ) { /* parent directory */
continue;
} else if ( 0 == strcmp(file_info.name, ".") ) {
_chdir(path);
fprintf(fplog, "%s $ %s\n", path, ptype);
dump(ptype);
} else {
memset(path_buf, 0, sizeof(path_buf));
STRCAT(path_buf, MAX_PATH, path);
STRCAT(path_buf,MAX_PATH,"\\");
STRCAT(path_buf,MAX_PATH,file_info.name);
recurse_path(path_buf, ptype);
}
}
} while ( 0 == _findnext(file_handle, &file_info) );
_findclose(file_handle);
}
}

int main(void)
{
/* specify the types of file you want to delete */
char types[]    = "*.aps|*.bsc|*.clw|*.dep|*.exp|*.idb|*.ilk|*.ncb"
"|*.obj|*.opt|*.pch|*.pdb|*.plg|*.res|*.sbr|*.tmp|*.trc";
char *delimiter = "|";
char *token     = NULL;

if ( NULL == ( fplog = fopen("del.log", "w") ) ) {
perror("write log to file failed(fopen)");
system("pause>nul");
exit(EXIT_FAILURE);
}

token = strtok(types, delimiter);
while (token != NULL) {
errno = 0;
recurse_path("E:\\myd\\work\\API\\tetris111003\\tetris", token);
if ( ENOMEM == errno ) {
fprintf(fplog, "concatenate two strings error(STRCAT)");
}

fprintf(fplog, "\n");
token = strtok(NULL, delimiter);
}

fclose(fplog);
system("pause>nul");
return 0;
}
不过指定types为"*.*"时还稍微有点不完美。因为这时遇到文件夹也要删除(不过目前我在dump函数中只使用了remove函数,而没使用_rmdir所以在日志中虽然会记录>>> delete .. ,但实际上文件夹并没有真的被删除), 所以就涉及到了文件夹删除的顺序问题(目前我写的递归函数在删除文件夹时会先删除父文件夹, 这样它先删除了"..",再删除".")。 可能需要依赖与栈了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  语言 path file c types token
相关文章推荐