首页 文章

日志文件轮换名称

提问于
浏览
0

我写了这个简单的C程序来改变旋转文件名 . 例如:对于 A_B_C_1 需要将其旋转到 A_B_C_2 ,如果 A_B_C 需要将其旋转到 A_B_C_1

问题是 strncat 没有按预期工作 . 它给我输出像:

A_B_C_1 (Works fine for single instance)
A_B_C_2
A_B_C_23
A_B_C_2324

使用的逻辑很简单: - 获取字符串中的最后一位数字(如果存在) . - 如果它不是简单地附加_1(这个工作正常) - 如果是 - 提取数字,增加它并附加到新字符串 .

有没有一些std库可以做到这一点?

在循环/多次调用此方法时出错....

我无法调试原因.....需要帮助,请指导 .

int getRotationFileName(char *sFileName,char *sNewFileName)
   {
   char sTmpFile[256];
    int newRotation;
    memset(sTmpFile,NULL,sizeof(sTmpFile));
    strncpy(sTmpFile, sFileName, strlen(sFileName));
    char *tokenPtr;
    strtok(sFileName,"_"); //a
    strtok(NULL, "_"); //b
    strtok(NULL, "_"); //c
    tokenPtr = strtok(NULL, "_"); //1
        printf("sTempFile [%s], sFileName [%s], token [%s]",
            sTmpFile,sFileName,tokenPtr);


    if(tokenPtr!= NULL)//Last - exists
    {

        newRotation = atoi(tokenPtr);
        int newLen = strlen(sTmpFile);
        int oneLen = strlen(tokenPtr);
        memset(sNewFileName, NULL, sizeof(sNewFileName));
        printf("sNewFileName is prior: %s and len is %d \n", 
        sNewFileName, (newLen-oneLen));
        printf("sTempName is prior: %s", sTmpFile);
    strncpy(sNewFileName,sTmpFile, (newLen-oneLen));

        printf("diff is %d\n", (newLen-oneLen));
        printf("sNewFileName before concat %s \n", sNewFileName);
        newRotation++;
        sprintf(sNewFileName,"%s%d",sNewFileName, newRotation);
        sNewFileName[strlen(sNewFileName)]='\0';
        printf("sNewFileName after concat %s \n", sNewFileName);
    }
    else
    {
        printf("in else TmpFile [%s] , New File [%s], len %d",sTmpFile,
     sNewFileName,strlen(sTmpFile));
        strcat(sTmpFile,"_1");
        strncpy(sNewFileName,sTmpFile, strlen(sTmpFile));
    }
    strcpy(sFileName, sNewFileName);
    printf("\nNew file created is %s\n",sNewFileName);
    return 1;

}

似乎是在线问题:strncpy(sNewFileName,sTmpFile,(newLen-oneLen));

反馈:对于Chrome浏览器,代码格式化程序在此网站上无法正常运行

6 回答

  • 0

    你的代码是......有点乱 . 您需要将算法拆分为多个步骤,每个步骤都应该易于执行:

    • 检查名称是否以数字结尾 . 如果是,请记录号码的开始位置,然后提取号码 . 如果没有,则表现为0结束 .

    • 增加数量 .

    • 通过连接前缀和数字(作为字符串)创建新字符串 .

    请注意,这些算法很复杂,通常最好让标准库为您生成唯一的名称 .

    这是一个解决方案:

    void rotateName(const char *oname, char *nname)
    {
        const char  *ptr;
        int         number, plen;
    
        for(ptr = oname; *ptr && !isdigit(*ptr); ptr++)
                ;
        if(*ptr == '\0')
                number = 0;
        else
                number = atoi(ptr);
        plen = ptr - oname;
        if(plen <= 0)
                return;
        memcpy(nname, oname, plen);
        sprintf(nname + plen, "%d", number + 1);
    }
    
  • 0

    使用例如

    int get_rotated_name(char *filename,char *rotatedname,size_t len)
    {
        int version = 0;
        int pos = strrchr(filename,'_');
    
        if(pos == -1)
          return 1;
        if(isdigit(filename[pos+1])) {
          version = atoi(&filename[pos+1];
          filename[pos] = 0;
       }
    
       version++;
       snprintf(rotatedname,len,"%s_%d",filename,version);
    
      return 0;
    }
    
  • 1

    对于常量文件名字符串,您不需要 strtok 活动 .

    • 将常量部分与 strncmp 进行比较以确认它,或者使用 sscanf

    • atoisscanf %d 拉出文件号整数

    • 进行比较并更改整数(使用模数运算等)

    • 使用新整数生成 sprintf 的新名称


    并且,如果您不需要实际生成先前传递的下一个文件名,只需保留一个常量字符串和一个与 sprintf 一起使用的旋转整数来生成下一个文件名 .
    我知道在所有情况下都可能无法使用 .

  • 0

    你真的想要旋转序列号吗?

    我建议不要这样做,并继续使用序列号增加文件名,这将有助于知道已打开了多少文件 .

    Parallaly可以维护文件名数组,并在每次打开新文件时旋转start-index和end-index并增加start-index . 当数组被填充时,只需删除end-index处的文件并继续 .

  • 0

    我会看一下字符串的结尾,如果它是一个数字,我会继续往返,直到我到达一个非数字字符,将这些添加到一个字符串,并保持位置(p) .

    • 'filename' =>''

    • 'filename_9' => '9'

    • 'filename-3786' => '3786'

    然后我将它转换为数字n,如果它是空的,我假设为零 .

    我会把原始字符串放到p,将n 1转换为字符串并连接它 .

    • 'filename' => 'filename2'

    • 'filename_9' => 'filename_10'

    • 'filename-3786' => 'filename-3787'

    您还可以在第p个字符中查找分隔符,如'','',' - ',然后删除它们,然后始终添加一个固定的分隔符,如 .

  • 0

    是否有一些std库可以做到这一点?

    我会使用logrotate(https://linux.die.net/man/8/logrotate)而不是重新发明轮子 .

    你只需要安装一个关闭并重新打开日志文件的sigusr1处理程序 . logrotate将为您旋转/重命名/压缩文件 .

    如果您不喜欢使用sigusr1处理程序,或者将其用于其他内容,那么您可以在日志例程中实现文件存在检查 . 如果日志文件已消失,这意味着发生了logrotate:关闭文件并使用相同的名称重新打开它 .

    快乐的伐木 .

相关问题