以下代码在不同操作系统上运行时产生不同的结果,特别是在Fedora 14 / CentOS 6.6下,最终显示的值是miin,在Fedora 9/17和CentOS 6.2下它是主要的。
虽然我确信有很多方法可以实现'main'的最终目标,但是这个代码深入到一个失败的程序中,这是使用内部函数逻辑的测试用例。我的问题是为什么这段代码在不同版本的Linux之间无法正常工作。
#include <stdio.h>
#include <string.h>
int main ()
{
char mival[30]="/main.html";
char *p;
char *newval;
printf ("mival: %s\n",mival);
p = strchr(mival,'\0');
while(*p != '/' && *p != '.')
--p;
if (*p == '.')
{
*p = '\0';
while(*p != '/')
--p;
}
*p = '\0';
newval = p+1;
strcpy(mival, newval);
printf ("mival: %s\n",mival);
}
答案 0 :(得分:4)
当您复制的字符串与目标重叠时,strcpy()
函数会导致未定义的行为。在这种情况下,您需要使用memmove()
。
如果您无法重写该功能,可以使用快速修复:复制该字符串会使strcpy()
不重叠:
char mival[30]="/main.html";
char mival2[60];
strcpy (mival2, mival);
strcat (mival2, mival);
/* Operatate on mival2 */
否则,我强烈建议你重写破损的功能。这是我的建议(简要测试):
#include <stdio.h>
#include <string.h>
int main ()
{
char mival[30]="/main.html";
size_t dot, start, len;
printf ("mival: %s\n",mival);
len = strlen (mival);
dot = len;
start = 0;
do {
if (mival[len] == '.') {
dot = len;
} else if (mival[len] == '/') {
start = len+1;
break;
}
} while (len--);
memmove (mival, mival+start, dot-start);
mival[dot-start] = 0;
printf ("mival: %s\n",mival);
return 0;
}
请注意,此代码在最后一个斜杠后面找到第一个点(这是我想要的),而您的代码找到 last 点。
您也可以使用strrchr()
找到最右边的斜杠,然后strchr()
找到斜杠后的第一个点,但我认为这种方法会让我更头疼。