在一次面试中,我被要求实现strcpy
的函数,并修复它以正确处理重叠字符串。我的实现很简单,如下所示。请问如何修改它:
- 使其能够检测到重叠字符串,并且
- 在检测到重叠后,如何处理重叠并继续进行拷贝?
char* my_strcpy(char *a, char *b) {
if (a == NULL || b == NULL) {
return NULL;
}
if (a > b) {
//we have an overlap?
return NULL;
}
char *n = a;
while (*b != '\0') {
*a = *b;
a++;
b++;
}
*a = '\0';
return n;
}
int main(int argc, char *argv[])
{
char str1[] = "wazzupdude";
char *after_cpy = my_strcpy(str1 + 2, str1);
return 0;
}
编辑:
根据@Secure的答案,可能的一种实现方法是:
char* my_strcpy(char *a, char *b) {
if (a == NULL || b == NULL) {
return NULL;
}
memmove(a, b, strlen(b) + 1);
return a;
}
如果我们不依赖于 memmove
,那么
char* my_strcpy(char *a, char *b) {
if (a == NULL || b == NULL) {
return NULL;
}
if (a == b) {
return a;
}
// case1: b is placed further in the memory
if ( a <= b && a + strlen(a) > b ) {
char *n = a;
while(*b != '\0') {
*a = *b;
a++; b++;
}
*a = '\0';
return n;
}
// case 2: a is further in memory
else if ( b <= a && b + strlen(b) > a ) {
char *src = b + strlen(b) - 1; // src points to end of b
char *dest = a;
while(src != b) {
*dest = *src;
dest--; src--; // not sure about this..
}
*a = '\0';
return a;
}
}
a > b
如何“检测重叠”?它只是测试两个地址。 - Blagovest Buyuklieva
,b
指向C字符串,则不需要使用if(a == NULL || b == NULL){ return NULL; }
。 - chux - Reinstate Monica