2017-02-10 8 views
0

私はsnprintfを使用して2つの文字列を連結しようとしています。 1文字または2文字、これ以上のことが起こります。最初の文字列の最後の文字がなぜsnprintfが2番目の文字列を変更していますか?

int main() 
{ 
    char str1[] = "foo", str2[] = "bar", str3[]= ""; 

    printf("%s %s\n", str1, str2); 

    snprintf(str3, strlen(str1) + strlen(str2) + 1, "%s %s", str1, str2); 

    printf("%s", str3); 

    return 0; 
} 

を繰り返して出力:あなたのコードで

foo bar 
foo oo 
+3

'str3'は' str1'と 'str2'の両方を保持するのに十分ではありません。 – d3L

+0

'str3 [] =" "'を '* str3 = malloc(strlen(str1)+ strlen(str2)+ 1)'に変更します。 –

+0

そして、あなたがそれを使い終わったら 'free(str3)'を忘れることはありません... –

答えて

3

問題はstr3str1str2の両方を保持するのに十分な大きさでないということです。

str3""に初期化するので、str3のサイズは1に設定されます。ここで

正しい方法:

#include <stdio.h> // snprintf 
#include <stdlib.h> // EXIT_FAILURE 
#include <string.h> // strlen 

int main() { 
    char str1[] = "foo"; 
    char str2[] = "bar"; 
    // The size we need is the length of str1, str2, + 1 for a space 
    // and + 1 for the NUL terminator. 
    size_t str3_size = strlen(str1) + strlen(str2) + 2; 

    char str3[str3_size]; 

    snprintf(str3, str3_size, "%s %s", str1, str2); 

    printf("%s", str3); 
} 

しかし、こと:

#include <stdio.h> // snprintf 
#include <stdlib.h> // malloc, free 
#include <string.h> // strlen 

int main() { 
    char str1[] = "foo"; 
    char str2[] = "bar"; 
    // We need to dynamically allocate the third buffer 
    // since its size is not determined at compile time. 
    // The size we need is the length of str1, str2, + 1 for a space 
    // and + 1 for the NUL terminator. 
    size_t str3_size = strlen(str1) + strlen(str2) + 2; 

    char *str3 = malloc(str3_size); 

    // NULL = out of memory 
    if (!str3) { 
     printf("oops!"); return EXIT_FAILURE; 
    } 

    snprintf(str3, str3_size, "%s %s", str1, str2); 

    printf("%s", str3); 

    // Don't forget to free malloc'd memory! 
    free(str3); 
} 

あなたが完全にmalloc関数をドロップすると、このようなスタック上の第3のバッファを割り当てることができC99コンパイラを使用している場合スタックに動的サイズのメモリを割り当てることは危険です!

また、適切なサイズを自動的に計算する関数asprintf(GNU拡張)もあります。ここでは同じ例です:

#include <stdio.h> // asprintf 
#include <stdlib.h> // free 

int main() { 
    char str1[] = "foo"; 
    char str2[] = "bar"; 
    char *str3 = NULL; 

    asprintf(&str3, "%s %s\n", str1, str2); 
    // str3 now contains a pointer to the allocated memory :) 

    // NULL = out of memory 
    if (!str3) { 
     printf("oops!"); return EXIT_FAILURE; 
    } 

    printf("%s", str3); 

    // Don't forget to free malloc'd memory! 
    free(str3); 
} 
+1

'strcat'とも言えますか? –

+1

'asprintf()'はGNU拡張であることに注意してください。 –

+0

私は私の答えでそれを編集しました。 – d3L

関連する問題