2016-10-11 138 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; 
}