strcat_s и проблема новичка с указателем символа

Я делаю простые упражнения с использованием Visual Studio. Используя функцию strcat_s, я получаю исключение нарушения через этот код:

char *str1;
str1 = (char *)malloc(20);
*str1 = "Ciao ";
char *str2 = "Marco";
strcat_s(str1, sizeof(str1), str2);
printf("%s", str1);

Теперь, если я использую предопределенный массив с фиксированным размером, strcat_s работает отлично. Как я могу использовать указатели на char вместо массива, чтобы он работал?

Любое другое решение или совет будет очень признателен.

Заранее спасибо.

2 ответа

Вы должны сначала скопировать строки в выделенную память. Если вам нравится знать длину строки, используйте strlen(), sizeof() возвращает размер типа данных в байтах. В вашем случае это указатель (4 байта на 32-битной, 8 байт на 64-битной машине). Следующий код должен работать правильно:

char *str1 = (char *)malloc(20);
strcpy(str1,"Ciao ");
char *str2 = (char *)malloc(20);
strcpy(str2,"Marco ");
strcat(str1, str2);
printf("%s", str1);

Есть некоторые проблемы с вашим кодом, и есть некоторые общие замечания по strcat_s,

Ваш код str1 = (char *)malloc(20); *str1 = "Ciao " не копирует Ciao; *str это один символ в первой позиции strи ваше выражение преобразует строковый литерал "Ciao " (который является указателем на последовательность символов) на некоторый отдельный символ (T в этом случае; Удивительно, не правда ли?). Нужно было бы использовать strcpy вместо. Массив, как char buffer[20] = "Ciao "напротив, работает, потому что этот (особый) случай не является присваиванием, а инициализатором массива.

Ваш код sizeof(str1) дает размер значения указателя, который, вероятно, 4 или же 8и не имеет ничего общего с реальным размером содержимого или зарезервированного блока памяти. Надо использовать strlen вместо.

Что касается strcat_sСледует учитывать, что он доступен не на всех платформах и что вам нужно знать об его особом поведении. Например, если вы звоните strcat_s(somebuffer, 3, "somestrlongerthan3"), который превышает максимальную длину 3 как предоставлено, somebuffer будет "пустой" строкой (т.е. первый символ будет установлен в \0,

Я бы предложил использовать strncat или же snprintf вместо. Смотрите следующие варианты:

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

int main () {

    char c = "Ciao ";  // Gives a compiler warning and yields 'T'

#define maxlen 20

    // Variant 1: start with initialized buffer, yet no "pointer" and dynamic allocation
    char resultBuffer[maxlen] = "Ciao ";
    size_t charactersRemaining = maxlen-strlen(resultBuffer)-1;
    strncat(resultBuffer, "Marco", charactersRemaining);

    // Variant 2: use dynamically allocated buffer and snprintf, with constant "Ciao".
    char *resultBuffer2 = malloc(maxlen);
    const char* second2 = "Marco";
    snprintf(resultBuffer2, maxlen, "Ciao %s", second2);

    // Variant 3: use dynamically allocated buffer and snprintf, with probably variable "Ciao" and "Marco"
    char *resultBuffer3 = malloc(maxlen);
    const char* first3 = "Ciao";
    const char* second3 = "Marco";
    snprintf(resultBuffer3, maxlen, "%s %s", first3, second3);

    return 0;
} 
Другие вопросы по тегам