2017-02-10 3 views
0

Я пытаюсь объединить две строки, используя snprintf, и работает для очень маленьких строк, например. 1 или 2 символа, и так далее. Последний символ первой строки повторяетсяПочему snprintf меняет вторую строку?

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 [] =" "' to '* str3 = malloc (strlen (str1) + strlen (str2) + 1)'. –

+0

И не забудьте «free (str3)», когда вы закончите использовать его ... –

ответ

3

проблема с вашим кодом, что str3 не является достаточно большим, чтобы держать как str1 и str2.

Поскольку инициализации str3 с "" размер str3 будет установлен в 1.

Вот правильный путь:

#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); 
} 

Если вы используете C99 компилятор вы можете уронить таНос целиком и выделить третий буфер на стеке, как это:

#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); 
} 

Но быть осторожно, хотя выделение динамической памяти в стеке может быть опасным!

Существует также функция 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