2016-10-11 133 views
0

我必须在C中创建标准库的一些元素的副本,并且必须创建一个strcat的副本。所以我必须创建一个连接C中两个字符串的函数。我知道C中的数组无法更改分配的大小。我被允许使用的唯一fonction是副本我做了strlen的,中的strstr,和write()...我的代码如下所示:如何创建一个strcat的副本?

char *my_strcat(char *dest, char *src) 
{ 
    int dest_size; 
    int src_size; 
    int current_pos; 
    int free_space; 
    int pos_in_src; 

    src_size = my_strlen(src); 
    dest_size = my_strlen(dest); 
    while (dest[current_pos] != '\0') 
     current_pos = current_pos + 1; 
    free_space = dest_size - current_pos; 
    if (free_space < src_size) 
     return (0); 
    while (src[pos_in_src] != '\0') 
    { 
     dest[current_pos] = src[pos_in_src]; 
     pos_in_src = pos_in_src + 1; 
     current_pos = current_pos + 1; 
    } 
    return (dest); 
} 

但我不知道如何申报我的蒸馏水和主要是src。 我不知道如何创建一个大尺寸的数组,并将其声明为像dest =“Hello \ 0”这样的字符串,但该数组仍然包含6个以上的字符。

你能帮助我吗?

+0

为什么不使用指针和动态内存分配?你不允许吗? – Cherubim

+2

目标大小不是'strlen(dest)' - 它只是当前长度。 – 4386427

+4

从man7.org:'这些字符串可能不重叠,并且 dest字符串必须有足够的空间用于结果。如果dest为 不够大,程序行为是不可预测的。换句话说:您不必担心内存(重新)分配。来电者负责。 – 4386427

回答

2
char dest[19] = "epite"; 
char *src = "chor42spotted"; 

my_strcat(dest, src); 

而且,阅读manstrcat(3)

的DEST字符串必须有结果了足够的空间。

https://linux.die.net/man/3/strcat

所以你的函数行为不正确,你并不需要检查是否有dest

1

足够的自由空间,你想要一个功能mystrcat它的行为完全一样STDLIB strcat的。

所以原型是

/* 
    concatenate src to dest 
    dest [in/out] - the string to add to (buffer must be large enough) 
    src [in] - the string to concatenate. 
    Returns: dest (useless little detail for historical reasons). 
*/ 
char *mystrcat(char *dest, const char *src); 

现在我们称呼它

int main(void) 
{ 
char buff[1024]; // nice big buffer */ 

strcpy(buff, "Hello "); 
mystrcat(buff, "world"); 

/* print the output to test it */ 
printf("%s\n", buff); 

return 0; 
} 

但我不打算写mystrcat你。这会让你的作业练习毫无意义。

+0

这不是我要求的(最后一行) – Orionss

+0

挑剔的原型是'char * strcat(char * restrict s1,const char * restrict s2)'。限制指针允许编译器更有效地行为,因为它可以假定参数不指向相同的内存。 – Lundin

1

该数组的第一个参数只需要足够大以包含两个字符串+一个空终止符。因此,例如,如果您有"hello""world",则需要5 + 5 +1 = 11个字符。例如:

#define LARGE_ENOUGH 11 

int main (void) 
{ 
    char str[LARGE_ENOUGH] = "hello"; 
    my_strcat(str, "world"); 
    puts(str); // gives "helloworld" 
} 

在实际应用中,一般会为数组分配空间,要么是同大量(几百个字节)或基于strlen的调用的长度。


至于实施本身,您的解决方案是不必要的复杂。请注意,真正的strcat将全部错误检查留给调用者。它很可能是这样实现的:

char* strcat (char* restrict s1, const char* restrict s2) 
{ 
    return strcpy(&s1[strlen(s1)], s2); 
} 

这里最重要的部分是要注意s2参数的const正确性。

restrict关键字只是来自C标准的微优化,它告诉编译器它可以假定指针指向不同的内存区域。

如果你想推出自己的版本,没有库函数调用只是为了好玩,它仍然很容易,你只需要两个循环。也许这样的事情:

char* lolcat (char* restrict s1, const char* restrict s2) 
{ 
    char* s1_end = s1; 
    while(*s1_end != '\0') // find the end of s1 
    { 
    s1_end++; 
    } 

    do // overwrite the end of s1 including null terminator 
    { 
    *s1_end = *s2; 
    s1_end++; 
    s2++; 
    } while(*s1_end != '\0'); // loop until the null term from s2 is copied 

    return s1; 
}