我写了这个简单的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结束 .
增加数量 .
通过连接前缀和数字(作为字符串)创建新字符串 .
请注意,这些算法很复杂,通常最好让标准库为您生成唯一的名称 .
这是一个解决方案:
使用例如
对于常量文件名字符串,您不需要
strtok
活动 .将常量部分与
strncmp
进行比较以确认它,或者使用sscanf
用
atoi
或sscanf %d
拉出文件号整数进行比较并更改整数(使用模数运算等)
使用新整数生成
sprintf
的新名称并且,如果您不需要实际生成先前传递的下一个文件名,只需保留一个常量字符串和一个与
sprintf
一起使用的旋转整数来生成下一个文件名 .我知道在所有情况下都可能无法使用 .
你真的想要旋转序列号吗?
我建议不要这样做,并继续使用序列号增加文件名,这将有助于知道已打开了多少文件 .
Parallaly可以维护文件名数组,并在每次打开新文件时旋转start-index和end-index并增加start-index . 当数组被填充时,只需删除end-index处的文件并继续 .
我会看一下字符串的结尾,如果它是一个数字,我会继续往返,直到我到达一个非数字字符,将这些添加到一个字符串,并保持位置(p) .
'filename' =>''
'filename_9' => '9'
'filename-3786' => '3786'
然后我将它转换为数字n,如果它是空的,我假设为零 .
我会把原始字符串放到p,将n 1转换为字符串并连接它 .
'filename' => 'filename2'
'filename_9' => 'filename_10'
'filename-3786' => 'filename-3787'
您还可以在第p个字符中查找分隔符,如'','',' - ',然后删除它们,然后始终添加一个固定的分隔符,如 .
我会使用logrotate(https://linux.die.net/man/8/logrotate)而不是重新发明轮子 .
你只需要安装一个关闭并重新打开日志文件的sigusr1处理程序 . logrotate将为您旋转/重命名/压缩文件 .
如果您不喜欢使用sigusr1处理程序,或者将其用于其他内容,那么您可以在日志例程中实现文件存在检查 . 如果日志文件已消失,这意味着发生了logrotate:关闭文件并使用相同的名称重新打开它 .
快乐的伐木 .