我编写了这个简单的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浏览器
答案 0 :(得分:1)
你的代码是......有点乱。您需要将算法拆分为多个步骤,每个步骤都应该易于执行:
请注意,这些算法非常有用,通常最好让标准库为您生成一个唯一的名称。
这是一个解决方案:
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);
}
答案 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;
}
答案 2 :(得分:0)
对于常量文件名字符串,您不需要strtok
个活动。
strncmp
进行比较以确认,或使用sscanf
atoi
或sscanf %d
sprintf
的新名称
并且,如果您不需要实际生成以前传递的下一个文件名,就像您的函数建议的那样,只需保留一个常量字符串和一个与sprintf
一起使用的旋转整数来生成下一个文件名。
我知道在所有情况下都可能无法使用。
答案 3 :(得分:0)
你真的想要旋转序列号吗?。
我建议不要这样做并继续使用序列号增加文件名,这将有助于了解已打开的文件数量。
Parallaly你可以维护文件名数组,并在每次打开新文件时旋转start-index和end-index并增加start-index。当数组被填充时,只需删除end-index处的文件并继续。
答案 4 :(得分:0)
我会查看字符串的结尾,如果它是一个数字,我会继续回去,直到我找到一个非数字字符,将它们添加到字符串中,并保持位置(p)。
然后我将它转换为数字n,如果它是空的,我假设为零。
我会将原始字符串取为p,将n + 1转换为字符串并将其连接起来。
您还可以在第p个字符中查找分隔符,例如'','_',' - ',然后删除它们,然后始终添加一个固定的分隔符,如_。
答案 5 :(得分:0)
是否有一些std库可以做到这一点?
我会使用logrotate(https://linux.die.net/man/8/logrotate)而不是重新发明轮子。
您只需要安装一个关闭并重新打开日志文件的sigusr1处理程序。 logrotate将为您旋转/重命名/压缩文件。
如果您不想使用sigusr1处理程序,或者已将其用于其他内容,则可以在日志例程中实现文件存在检查。如果日志文件已消失,这意味着发生了logrotate:关闭文件并使用相同的名称重新打开它。
快乐的伐木。