2011-05-05 350 views
32

我想附加兩個字符串。我使用了以下命令:C字符串追加

new_str = strcat(str1, str2); 

該命令更改str1的值。我想要new_str成爲str1str2的連接,並且同時str1不會被改變。

+2

你說得對,就是這樣。 – 2011-05-05 16:35:36

+1

由於各種原因,您可能需要跟蹤'str1','str2'和'new_str'的​​大小,並使用'strncat'而不是'strcat')。這將有助於避免一些緩衝區溢出錯誤。 – 2011-05-05 16:38:21

回答

42

您需要分配新的空間爲好。考慮下面的代碼片段:

char * new_str ; 
if((new_str = malloc(strlen(str1)+strlen(str2)+1)) != NULL){ 
    new_str[0] = '\0'; // ensures the memory is an empty string 
    strcat(new_str,str1); 
    strcat(new_str,str2); 
} else { 
    fprintf(STDERR,"malloc failed!\n"); 
    // exit? 
} 

你可能要考慮strnlen(3)這是稍微更安全。

更新,見上。在C運行時的某些版本中,由malloc返回的內存未初始化爲0.我相信較新的C規範實際上需要malloc才能這樣做,但爲防萬一,將第一個字節new_str設置爲零可確保它看起來像像strcat的空字符串。

+8

'malloc'總是可以返回垃圾,甚至可以在現代系統上使用。 'calloc'給你零記憶。 – Kornel 2012-12-22 23:32:09

+1

而calloc通常需要sizeof(空間)時間來做到這一點。如果你正在做很多字符串,並且對指針很小心,那麼可以節省大量的冗餘指令。 – 2012-12-24 04:01:46

+1

請刪除不正確的猜想:「我相信新的C規範實際上需要malloc來這樣做」。另外,將第一個字節設置爲零根據定義使它成爲一個零長度的字符串(看起來不像)。 – 2016-05-24 06:07:15

1

然後你必須先strncpy str1進入new_string。

5

做到以下幾點:
strcat(new_str,str1);
strcat(new_str,str2);

+3

注意new_str必須初始化爲空字符串。 – indiv 2011-05-05 16:38:27

+3

和適當的大小! – 2011-05-05 18:49:01

+0

當new_str不能容納空格或(* new_str)時,這會崩潰!= 0 – 2016-05-24 05:59:37

-3

你可以嘗試這樣的事情:

strncpy(new_str, str1, strlen(str1)); 
strcat(new_str, str2); 

更多關於函數strncpy信息:strcat的的http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

+1

這太可怕了,在這裏執行strlen(str1)沒有意義,而使用strncpy(),一個簡單的strcpy()做同樣的事情。如果你使用sizeof new_str,那麼會有一個問題。 – unwind 2011-05-05 16:40:52

+1

我不知道這是否是拼寫錯誤或對'strncpy'的'n'參數的嚴重誤解,但是您需要提供'new_str'的​​緩衝區大小,而不是'str1'的長度。如果'new_str'包含5個字符,而'str1'包含1000個字符,會發生什麼? – indiv 2011-05-05 16:49:17

+0

@indiv沒有誤解。 strncpy reference - num - 將源的第一個數字字符複製到目標。當然,在這個操作之前應該檢查源緩衝區的長度 – Ulterior 2013-06-12 04:11:15

-2

手冊頁說,ARG1和arg2被附加到arg1 ..並返回s1的指針。如果你不想打擾str1,str2,那麼你已經編寫了你自己的函數。

char * my_strcat(const char * str1, const char * str2) 
{ 
    char * ret = malloc(strlen(str1)+strlen(str2)); 

    if(ret!=NULL) 
    { 
    sprintf(ret, "%s%s", str1, str2); 
    return ret; 
    } 
    return NULL;  
} 

希望這能解決你的目的

+1

我不喜歡使用printf來進行字符串連接。它可以很容易地使用strcpy,strcat甚至memcpy – eyalm 2011-05-05 16:43:09

+0

ya你寫的..但我想給你一個單一的聲明..或者你可以做strcpy(ret,str1),然後strcat(ret,str2)。或者如你所說,memcpy會更快。 – maheshgupta024 2011-05-05 16:52:57

+2

你有多少空間分配給複製的字符串?提示:這不是strlen(str)。 – 2011-05-05 18:51:37

-1
strcpy(str1+strlen(str1), str2); 
+0

這會失敗,因爲str1必須保持不變(根據問題)。 – 2016-05-24 06:02:00

+2

您能否解釋您的答案如何解決問題中的問題?僅有代碼的答案並不是很有用,特別是對於那些偶然發現這篇文章的讀者。謝謝! – Cristik 2016-05-24 06:22:09

0

你可以使用asprintf兩者連接成一個新的字符串:

char *new_str; 
asprintf(&new_str,"%s%s",str1,str2); 
+0

這是固有的特定於'asnprintf'可用的平臺。這不是「標準」。 – lpapp 2014-12-03 11:39:27

0

我需要追加子用來創建SSH命令,我解決了sprintf(Visual Studio的2013年)

char gStrSshCommand[SSH_COMMAND_MAX_LEN]; // declare ssh command string 

strcpy(gStrSshCommand, ""); // empty string 

void appendSshCommand(const char *substring) // append substring 
{ 
    sprintf(gStrSshCommand, "%s %s", gStrSshCommand, substring); 
} 
1

我寫了一個函數支持動態變量字符串追加,如PHP str追加:str + str + ...等。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdarg.h> 

int str_append(char **json, const char *format, ...) 
{ 
    char *str = NULL; 
    char *old_json = NULL, *new_json = NULL; 

    va_list arg_ptr; 
    va_start(arg_ptr, format); 
    vasprintf(&str, format, arg_ptr); 

    // save old json 
    asprintf(&old_json, "%s", (*json == NULL ? "" : *json)); 

    // calloc new json memory 
    new_json = (char *)calloc(strlen(old_json) + strlen(str) + 1, sizeof(char)); 

    strcat(new_json, old_json); 
    strcat(new_json, str); 

    if (*json) free(*json); 
    *json = new_json; 

    free(old_json); 
    free(str); 

    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    char *json = NULL; 

    str_append(&json, "name: %d, %d, %d", 1, 2, 3); 
    str_append(&json, "sex: %s", "male"); 
    str_append(&json, "end"); 
    str_append(&json, ""); 
    str_append(&json, "{\"ret\":true}"); 

    int i; 
    for (i = 0; i < 10; i++) { 
     str_append(&json, "id-%d", i); 
    } 

    printf("%s\n", json); 

    if (json) free(json); 

    return 0; 
} 
0

考慮使用偉大但未知的open_memstream()函數。用法

FILE *open_memstream(char **ptr, size_t *sizeloc);

例子:

// open the stream 
FILE *stream; 
char *buf; 
size_t len; 
stream = open_memstream(&buf, &len); 

// write what you want with fprintf() into the stream 
fprintf(stream, "Hello"); 
fprintf(stream, " "); 
fprintf(stream, "%s\n", "world"); 

// close the stream, the buffer is allocated and the size is set ! 
fclose(stream); 
printf ("the result is '%s' (%d characters)\n", buf, len); 
free(buf); 

如果你事先不知道要追加什麼長度,這是方便和安全的管理比自己緩衝。