简单的字符串操作会在Linux版本中产生不同的结果 - 为什么?

时间:2014-11-17 15:20:20

标签: c

以下代码在不同操作系统上运行时产生不同的结果,特别是在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);   
}

1 个答案:

答案 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()找到斜杠后的第一个点,但我认为这种方法会让我更头疼。