首页 > 代码库 > 批量重命名文件
批量重命名文件
今天突然想给桌面换张壁纸,打开原来的壁纸文件夹,很多当时觉得不错的壁纸现在已经不能看了,删掉一些之后,壁纸文件的名称变得断断续续。当时下载时是按照数字顺序命名的,现在看上去多少有些别扭。于是突发奇想,能否批量给某一目录下的文件重命名,比如我现在的壁纸文件夹。
首先我想到应该要打开一个目录,猜想是否有opendir之类的函数?果然有!在头文件<dirent.h>下面:
DIR* __cdecl __MINGW_NOTHROW opendir (const char*);
返回值是DIR*,查看DIR的声明(opendir的上一个声明):
/* * This is an internal data structure. Good programmers will not use it * except as an argument to one of the functions below. * dd_stat field is now int (was short in older versions). */ typedef struct { /* disk transfer area for this dir */ struct _finddata_t dd_dta; /* dirent struct to return from dir (NOTE: this makes this thread * safe as long as only one thread uses a particular DIR struct at * a time) */ struct dirent dd_dir; /* _findnext handle */ intptr_t dd_handle; /* * Status of search: * 0 = not started yet (next entry to read is first entry) * -1 = off the end * positive = 0 based index of next entry */ int dd_stat; /* given path for dir with search pattern (struct is extended) */ char dd_name[1]; } DIR;
看了注释狂汗。。。
紧接着opendir函数的是readdir,这个又是我想要的,返回一个结构体指针:
struct dirent* __cdecl __MINGW_NOTHROW readdir (DIR*);
这个结构体是DIR结构体的成员,再查看struct dirent的声明:
struct dirent { long d_ino; /* Always zero. */ unsigned short d_reclen; /* Always zero. */ unsigned short d_namlen; /* Length of name in d_name. */ char d_name[FILENAME_MAX]; /* File name. */ };
很清晰,我想要的是d_name成员,这是目录下的文件名,只要用rename函数把文件名改掉即可,注意返回值小于0表示失败。
_CRTIMP int __cdecl __MINGW_NOTHROW rename (const char*, const char*);
遍历所有文件后记得关闭文件closedir。
完整的C代码:
#include <stdio.h> #include <dirent.h> #include <stdlib.h> #include <string.h> #define DIRNAMECOUNT 100 #define COMMONCOUNT 90 #define EXTENSION 9 int main(int argc, char *argv[]) { DIR *dirp; struct dirent *dirt; char dir_name[DIRNAMECOUNT]; char common_name[COMMONCOUNT] = ""; char extension[EXTENSION] = ""; int file_count = 1; printf("Please input a common name: \n"); scanf("%s", common_name); printf("Please input a extension: \n"); scanf("%s", extension); if (argc != 2) { printf("argument miss\n"); exit(1); } if ((dirp = opendir(argv[1])) == NULL) { printf("open dir %s failed\n", argv[1]); exit(1); } chdir(argv[1]); while ((dirt = readdir(dirp)) != NULL) { if (strcmp(dirt->d_name, "..") && strcmp(dirt->d_name, ".")) { memset(dir_name, 0, sizeof(dir_name)); sprintf(dir_name, "%s_%d%s%s", common_name, file_count++, ".", extension); if (rename(dirt->d_name, dir_name) < 0) { printf("rename failed\n"); exit(1); } } } closedir(dirp); return 0; }
这样只要输入文件名相同的部分(如wallpapers),以及扩展名(jpg),则文件可以按照序号重新命名。这样,所有的壁纸就都重命名了!
思考:
1.可以先读取文件的扩展名,保持更改时不变,否则文件无法查看(在windows系统下)。strtok函数可以分割字符串,以“.”分割获取最后一个字符串即扩展名。
2.对于要在原文件名的基础上增加新的字符,可以更改为sprintf(dir_name + strlen(dirt->d_name), ...)。
2.可以将自动获取当前目录的文件夹,getcwd函数可以做到。但是应该考虑到,可执行程序也会被重命名。可以在程序中过滤掉.exe文件,这取决于个人的把握。
批量重命名文件