修改文件后缀的C语言实现

        在实际的软件开发项目中,大家也许会遇到修改文件的后缀的需求(例如,将doc格式修改为docx格式)。本文提供了修改文件后缀的C语言实现,并演示了修改文件后缀的过程。

        1. C程序实现

/**********************************************************************
* 版权所有 (C)2014, ZhouZhaoxiong。
*
* 文件名称: ChangeSuffix.c
* 文件标识:无
* 内容摘要:对文件的后缀进行转换
* 其它说明:无
* 当前版本: V1.0
* 作    者:周兆熊
* 完成日期: 20141117
**********************************************************************/
 
#include
#include
#include
#include
#include 
 
 
#defineMAX_FILESUFFIX_NUM   10  // 能够配置的文件后缀最大个数
#defineMAX_FILESUFFIX_LEN   10  // 单个文件后缀的最大长度
 
 
#define _MAXPATH 1024
int GetAppConfig(void);
voidParseFileSuffix(char *pSzSuffixBuf, int iType);
int GetFileExt(char*pFilePath, char *pOutFileExt);
int main(int argc, char*argv[]);
void Check(char*pPath);
voidModifyFileName(char* pFilePath, char *pFileName);
 
 
// 全局配置
typedef struct
{
    int iOld2NewOrNew2Old;                                         // 新老后缀的转换
    charszOldSuffix[MAX_FILESUFFIX_NUM][MAX_FILESUFFIX_LEN];       // 旧的文件后缀
    charszNewSuffix[MAX_FILESUFFIX_NUM][MAX_FILESUFFIX_LEN];       // 新的文件后缀
} Config_T;
 
 
Config_T g_tConfig;
 
 
/****************************************************************
 * 功能描述: 获取全局配置
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0-执行成功    -1-执行失败
 * 其它说明:无
 * 修改日期        版本号        修改人      修改内容
 *--------------------------------------------------------------
 * 20141117       V1.0           zzx         新建
 ****************************************************************/
int GetAppConfig(void)
{
    char szIniFile[128]   ={0};
    char szOldSuffix[256] = {0};
    char szNewSuffix[256] = {0};
 
 
    memset(&g_tConfig, 0x00,sizeof(Config_T));
 
 
    GetCurrentDirectory(sizeof(szIniFile)-1,szIniFile);
    strcat(szIniFile, "\\");
    strcat(szIniFile, "Config.ini");
 
 
    // 读取各个配置的值
    // 获取新旧后缀的转换标志
    g_tConfig.iOld2NewOrNew2Old =GetPrivateProfileInt("General", "Old2NewOrNew2Old", 1,szIniFile);
 
 
    // 获取旧的后缀并解析
    GetPrivateProfileString("General", "OldSuffix","", szOldSuffix, sizeof(szOldSuffix), szIniFile);
    if (strlen(szOldSuffix) == 0)
    {
        return -1;
    }
    ParseFileSuffix(szOldSuffix, 1);
 
 
    // 获取新的后缀并解析
    GetPrivateProfileString("General", "NewSuffix","", szNewSuffix, sizeof(szNewSuffix), szIniFile);
    if (strlen(szNewSuffix) == 0)
    {
        return -1;
    }
    ParseFileSuffix(szNewSuffix, 2);
 
    return 0;
}
 
 
/****************************************************************
 * 功能描述: 对读取到的后缀配置进行解析
 * 输入参数: pSzSuffixBuf: 包含所有配置值的缓存
             iType:解析新旧后缀的标志
 * 输出参数: 无
 * 返 回 值: 无
 * 其它说明:无
 * 修改日期       版本号         修改人      修改内容
 *--------------------------------------------------------------
 * 20141117       V1.0           zzx         新建
 ****************************************************************/
void ParseFileSuffix(char*pSzSuffixBuf, int iType)
{
    char szFileSuffix[128] = {0};
    char *t     = NULL;
    char *p      = NULL;
    int   h      = 0;
    int   iLen   = 0;
    int   iCpLen = 0;
 
    if (pSzSuffixBuf == NULL)
    {
        return;
    }
 
    memcpy(szFileSuffix, pSzSuffixBuf,sizeof(szFileSuffix));
 
 
    iLen = strlen(szFileSuffix);
    if (iLen >= sizeof(szFileSuffix))
    {
        iLen = sizeof(szFileSuffix);
    }
 
    if (szFileSuffix[iLen-1] != ';')
    {
        strcat(szFileSuffix, ";");
    }
 
 
    t = szFileSuffix;
 
    while ((p=strchr(t, ';')) != NULL)
    {
        if ((p-t) >= MAX_FILESUFFIX_LEN)
        {
            iCpLen = MAX_FILESUFFIX_LEN;
        }
        else
        {
            iCpLen = p-t;
        }
 
 
        switch (iType)
        {
            case 1:      // 解析旧的后缀
            {
               strncpy(g_tConfig.szOldSuffix[h], t, iCpLen);
                break;
            }
 
 
            case 2:      // 解析新的后缀
            {
               strncpy(g_tConfig.szNewSuffix[h], t, iCpLen);
                break;
            }
 
 
            default:
            {
                break;
            }
        }
 
        t = p + 1;
 
        h ++;
 
        if (h >= MAX_FILESUFFIX_NUM)
        {
            break;
        }
    }    
 
    return;
} 
 
 
/****************************************************************
 * 功能描述: 获取文件后缀
 * 输入参数: pFilePath-包含路径的文件名
 * 输出参数: pOutFileExt-文件后缀
 * 返  回值: 0-执行成功    -1-执行失败
 * 其它说明:无
 * 修改日期       版本号        修改人      修改内容
 *--------------------------------------------------------------
 * 20141117       V1.0           zzx         新建
 ****************************************************************/
int GetFileExt(char*pFilePath, char *pOutFileExt)
{
       char *pDest = NULL;
       int iResult = 0;
       int iFullPathLen = 0;
       int iFileExtLen  = 0;
       char szFullPathName[_MAXPATH] = {0};
 
 
       if ((NULL == pFilePath) || (NULL == pOutFileExt))
       {
              return -1;
       }
 
 
       _snprintf(szFullPathName,sizeof(szFullPathName)-1, "%s", pFilePath);
       iFullPathLen = strlen(szFullPathName);
 
 
       pDest = strrchr(szFullPathName, '.');
       if (NULL == pDest)
       {
           return -1;
       }
 
 
       iResult = pDest - szFullPathName + 1;
 
 
       iFileExtLen = iFullPathLen - iResult;
       if (iFileExtLen > 0)
       {
           memcpy(pOutFileExt, szFullPathName+iResult,iFileExtLen);
       }
       else
       {
           *pOutFileExt = 0;
       }
 
       return 0;
}
 
 
/****************************************************************
 * 功能描述: 修改文件后缀
 * 输入参数: pFilePath-文件路径
 * 输出参数: pOutFileExt-文件后缀
 * 返 回 值: TRUE-执行成功    FALSE-执行失败
 * 其它说明:无
 * 修改日期        版本号        修改人      修改内容
 *--------------------------------------------------------------
 *  20141117       V1.0           zzx         新建
 ****************************************************************/
voidModifyFileName(char* pFilePath, char *pFileName)
{
    HANDLE hFile                = NULL;
    int  iLoopFlag               = 0;
    int iResult                 = 0;
    int iNameLen                = 0;
    int  iTotalExtType           = 0;
    char szFileTitle[_MAXPATH]   = {0};
    char szFilename[_MAXPATH]    = {0};
    char szNewFilename[_MAXPATH] = {0};
    char szFileExt[_MAXPATH]    = {0};
 
 
    if((NULL == pFilePath) || (NULL == pFileName))
    {
        return;
    }
 
 
       if (-1 == GetFileExt(pFileName, szFileExt))
       {
              return;
       }
 
 
       printf("ext:[%s] file:[%s]\n", szFileExt,pFileName);
 
 
       iNameLen = strlen(pFileName)-strlen(szFileExt);
       memcpy(szFileTitle, pFileName, iNameLen);
 
 
       iTotalExtType = sizeof(g_tConfig.szOldSuffix) /sizeof(g_tConfig.szOldSuffix[0]);
       for (iLoopFlag = 0; iLoopFlag = iTotalExtType)
       {
              printf("非修改文件类型: %s\n", szFileExt);
              return;
       }
 
 
    _snprintf(szFilename, sizeof(szFilename)-1,"%s\\%s", pFilePath, pFileName);
 
 
       if (1 == g_tConfig.iOld2NewOrNew2Old) // 变为新的后缀
       {
              _snprintf(szNewFilename, sizeof(szNewFilename)-1,"%s\\%s%s", pFilePath, szFileTitle, g_tConfig.szNewSuffix[iLoopFlag]);
       }
       else
       {
              _snprintf(szNewFilename, sizeof(szNewFilename)-1,"%s\\%s%s", pFilePath, szFileTitle,g_tConfig.szOldSuffix[iLoopFlag]);
       }
 
 
    iResult = rename(szFilename,szNewFilename);
    if (iResult != 0)
    {
       printf("Could not rename'%s'\n", szFilename);
    }
    else
    {
       printf("File '%s' renamed to'%s'\n", szFilename, szNewFilename);
    }
 
 
    return;
}
 
 
/****************************************************************
 * 功能描述: 扫描文件目录
 * 输入参数: pPath-文件路径
 * 输出参数: 无
 * 返回值: TRUE-执行成功    FALSE-执行失败
 * 其它说明:无
 * 修改日期        版本号        修改人      修改内容
 *--------------------------------------------------------------
 * 20141117       V1.0           zzx         新建
 ****************************************************************/
void Check(char *pPath)
{
       struct _finddata_t hFile; //定义结构体变量
       long handle;
       char szPath[_MAXPATH] = {0};
 
 
       memset(szPath, 0, sizeof(szPath));
       _snprintf(szPath, sizeof(szPath)-1, "%s\\*", pPath);
 
 
       handle =_findfirst(szPath, &hFile);     // 查找所有文件
       if (handle == -1)
       {
              printf("目录 %s 为空\n", pPath);
              return;
       }
       else
       {
              if (hFile.attrib &_A_SUBDIR) // 是目录
              {
                     if (hFile.name[0] != '.') // 文件名不是'.'或'..'时
                     {
                            memset(szPath, 0, sizeof(szPath));
                            _snprintf(szPath, sizeof(szPath)-1,"%s\\%s", pPath, hFile.name);
                            printf("检查目录: %s\n", szPath);
 
 
                            Check(szPath);   // 继续遍历
 
 
                            Sleep(10);
                     }
              }
              else    // 如果第一个实体不是目录,显示该文件
              {
                     // 再获得文件的完整的路径名(包含文件的名称)
                 memset(szPath,0, sizeof(szPath));
                     _snprintf(szPath, sizeof(szPath)-1,"%s\\%s", pPath, hFile.name);
                     ModifyFileName(pPath, hFile.name);
              }
 
 
      // 继续对当前目录中的下一个子目录或文件进行与上面同样的查找
      while (!(_findnext(handle, &hFile)))
        {
                     if (hFile.attrib &_A_SUBDIR ) // 是目录                       
                     {
                            if (hFile.name[0] != '.') // 文件名不是'.'或'..'时
                            {
                                   memset(szPath, 0, sizeof(szPath));
                                   _snprintf(szPath,sizeof(szPath)-1, "%s\\%s", pPath, hFile.name);
                                   printf("检查目录: %s\n", szPath);
 
 
                                   Check(szPath);       // 继续遍历
 
 
                                   Sleep(10);
                            }
                     }
                     else    //如果第一个实体不是目录,显示该文件
                     {
                       memset(szPath, 0, sizeof(szPath));
                            _snprintf(szPath, sizeof(szPath)-1,"%s\\%s", pPath, hFile.name);
                            ModifyFileName(pPath, hFile.name);
                     }
              }
 
 
              _findclose(handle);
       }
}
 
 
/****************************************************************
 * 功能描述: 主函数
 * 输入参数: argc-输入的整型入参
             argv-输入的字符型入参
 * 输出参数: 无
 * 返回值: 0-执行成功    -1-执行失败
 * 其它说明:无
 * 修改日期        版本号        修改人      修改内容
 *--------------------------------------------------------------
 * 20141117       V1.0           zzx         新建
 ****************************************************************/
int main(int argc, char*argv[])
{
    char szPathName[1000] = {0};
    int  iPathLen = 0;
    int iRetVal  = 0;
 
 
    printf("starting...\n");
 
 
    // 先读取全局配置
    iRetVal = GetAppConfig();
    if (iRetVal != 0)
    {
        return -1;
    }   
 
 
       if (4 != argc)
       {
              printf("argc=%d\n", argc);
              printf("用法: touch.exe 目录名保持天数是否恢复\n例1: touch.exe D:\\work 60 1\n例2: touch.exe \"D:\\w o rk\" 60 0\n");
              return -1;
       }
       else
       {
              char szTempPath[1000] = {0};
 
 
              //目录名称
              strncpy(szTempPath, argv[1], sizeof(szTempPath)-1);
              iPathLen = strlen(szTempPath);
              if (iPathLen = 'A') &&(szTempPath[0] = 'a') &&(szTempPath[0] 

        2. 修改后缀的过程

        step 1

       在本地的D盘中,有一个叫做Test的文件夹,该文件夹下有一个命名为123.doc的文件,如下图所示:

 修改文件后缀的C语言实现

        在任一文件夹下新建两个文件夹,分别命名为Old2New(表示旧的后缀修改为新的后缀)New2Old (表示新的后缀修改为旧的后缀),并将C程序运行生成的ChangeSuffix.exe拷贝到两个文件夹下。

 

        step 2

       在这两个文件夹下新建名为Config.ini的配置文件,该文件中的各个配置项如下:

[General]

; 将老的后缀转换为新的后缀,或是将新的后缀转换为老的后缀,1--Old -> New, 2--New -> Old

Old2NewOrNew2Old  =

 

; 旧的文件后缀(支持配置多个, 中间有;隔开)

OldSuffix = doc;xls;ppt

 

; 新的文件后缀(支持配置多个, 中间有;隔开)

NewSuffix = docx;xlsx;pptx

       

       其中,Old2New文件夹下的Old2NewOrNew2Old设置为1New2Old文件夹下的Old2NewOrNew2Old设置为2,其它配置项保持一致。

 

        step 3

        在Old2New文件夹下新建名为update.bat的批处理文件,该文件的内容为:

        ChangeSuffix  "D:\\Test" 60 0

        其中,D:\\Test为待修改后缀的文件的存放路径。

 

        在New2Old文件夹下新建名为update_restore.bat的批处理文件,该文件的内容为:

        ChangeSuffix  "D:\\Test" 60 1

       其中,D:\\Test为待修改后缀的文件的存放路径。

 

       “Old2NewNew2Old两个文件夹下的文件存放情况如下:

 修改文件后缀的C语言实现

 修改文件后缀的C语言实现

       step 4

       分别双击update.batupdate_restore.bat,即可实现旧新和新旧后缀的转换功能。

 

 

(本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)

 

上一篇:学习JavaFX Script,第一部分:针对Java程序员的JavaFX介绍


下一篇:纪念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步骤和工作原理介绍