2013-10-17 16 views
1

我在C上工作,想要實現字符串連接功能。 我實現如下功能:如何在字符串連接中處理較小尺寸的情況?

void mystr_concat(char* dest, char* src) 
{ 
     char* temp = dest; 
     while(*temp) 
     { 
       temp++; 
     } 

     while(*src) 
     { 
       *temp++ = *src; 
       src++; 
     } 
     *temp = '\0'; 
     return; 
} 

上述程序的輸出是其追加「SRC」字符串「DEST」字符串。

如果用戶傳遞了一個長度很小的「dest」字符串,以至於它不能再附加「src」字符串。

例如用戶有這樣的字符串和調用功能

char dest[6] = "abcnd"; 
char src[100] = "zdfhjksdfskdfsdfsdfj"; 
mystr_concat(dest, src) 

在這種情況下 如何檢查上述加薪的條件和要求的解決方案來解決這個問題?

+0

打擾您需要將最大目的地大小傳遞給您的功能,或者所有投注都關閉。 (和不相關的,你的第二個while循環可以簡單地爲'while((* dst ++ = * srC++));'並且你可以在末尾拋出空字符集。 – WhozCraig

+0

http://www.openbsd.org/cgi-bin/man.cgi?query=strlcat - 基本上,做那個功能 – millimoose

+1

@Dayalrai:在這裏使用'sizeof'是錯誤的建議。在指針上使用'sizeof'會返回指針變量的大小,而不是指針可能引用的數組的大小。 – alk

回答

0

請注意,當字符串作爲函數的參數傳遞時,會腐朽爲字符指針。並且在運行時不知道其指針給出的存儲區的大小。所以你mystr_concat無法知道的dest大小(除非你給大小在某種程度上,例如由顆粒尺寸在作爲附加功能放慢參數如聲明

void mystr_concat(char* dest, size_t destsize, char* src) 

那麼你可能會如

char destbuf[36]; 
strncpy (destbuf, sizeof(destbuf) /*i.e. 36*/, "start"); 
mystr_concat(destbuf, sizeof(destbuf), "some-more"); 

叫它請注意,標準snprintf(3)函數有一個類似的約定。

另一種可能的方法是確定您的函數返回一個堆分配字符串,並且它的責任來電者free那個字符串。然後,你可以編寫

char *my_string_catenation (const char* s1, const char* s2) 
{ 
    if (!s1||!s2) return NULL; 
    size_t s1len = strlen(s1); 
    size_t s2len = strlen(s2); 
    char* res = malloc(s1len+s2len+1); 
    if (!res) 
    { perror("my_string_catenation malloc"); exit(EXIT_FAILURE); }; 
    memcpy (res, s1, s1len); 
    memcpy (res+s1len, s2, s2len); 
    res[s1len+s2len] = (char)0; 
    return res; 
} 

然後你可能會喜歡

char buf[32]; 
snprintf(buf, sizeof(buf), "+%d", i); 
char* catstr = my_string_catenation((i>30)?"foo":"boo", buf); 
do_something_with(catstr); 
free(catstr), catstr = NULL; 

上面的例子是有點笨代碼的事情,因爲人們可以只使用snprintfmy_string_catenation但我想不出一個短的更好的例子。

在C庫中,常見的有約定關於誰負責釋放一些堆分配的數據。你應該記錄這樣的約定(至少在聲明它們的頭文件中的註釋中)。

也許你可能有興趣使用Boehm's conservative garbage collector;您將使用GC_MALLOC而不是malloc等等,而您不會爲free ...

2

C不對數組引用執行任何邊界檢查。如果您需要完成此操作,則需要將函數傳遞給目標數組的最大大小,然後驗證源是否適合(或者根據需要決定截斷它),還是引入額外的數據結構以跟蹤典型的Pascal實現以每個字符串的最大長度爲前綴添加字符串的長度。

這兩種解決方案都不是自動的,並且以安全的方式支持此功能需要使用Java或C#等語言來防止使用不安全的構造。

相關問題