Подтвердить что ты не робот

Почему мне сначала нужно strcpy() перед strcat()?

Почему этот код создает проблемы во время выполнения:

char stuff[100];
strcat(stuff,"hi ");
strcat(stuff,"there");

но это не так?

char stuff[100];
strcpy(stuff,"hi ");
strcat(stuff,"there");
4b9b3361

Ответ 1

strcat будет искать нуль-терминатор, интерпретировать это как конец строки и добавить туда новый текст, перезаписывая нулевой ограничитель в процессе и записывая новый нуль-терминатор в конце конкатенация.

char stuff[100];  // 'stuff' is uninitialized

Где нулевой ограничитель? stuff не инициализирован, поэтому он может начинаться с NUL, или он может не иметь NUL в любом месте.

В С++ вы можете сделать это:

char stuff[100] = {};  // 'stuff' is initialized to all zeroes

Теперь вы можете сделать strcat, потому что первый символ "stuff" является нулевым терминатором, поэтому он будет добавляться в нужное место.

В C вам все равно нужно инициализировать "материал", что можно сделать несколькими способами:

char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
                 // so 'stuff' is effectively ""
strcpy(stuff, "hi ");  // this initializes 'stuff' if it not already.

Ответ 2

В первом случае stuff содержит мусор. strcat требует, чтобы и пункт назначения, и источник содержали соответствующие строки с нулевым завершением.

strcat(stuff, "hi ");

сканирует stuff для завершающего символа '\0', где он начнет копирование "hi ". Если он не найдет его, он сработает с конца массива, и могут произойти сколь угодно плохие вещи (т.е. Поведение undefined).

Один из способов избежать проблемы:

char stuff[100];
stuff[0] = '\0';      /* ensures stuff contains a valid string */
strcat(stuff, "hi ");
strcat(stuff, "there");

Или вы можете инициализировать stuff пустой строкой:

char stuff[100] = "";

который заполнит все 100 байтов stuff нулями (повышенная ясность, вероятно, стоит какой-то незначительной проблемы с производительностью).

Ответ 3

Потому что stuff не инициализируется перед вызовом strcpy. После объявления stuff не является пустой строкой, это неинициализированные данные.

strcat добавляет данные в конец строки - то есть находит нулевой ограничитель в строке и после этого добавляет символы. Неинициализированная строка не поддерживает нулевой ограничитель, поэтому strcat может сбой.

Если вам нужно было выполнить инициализацию stuff, как показано ниже, вы можете выполнить команду strcat:

char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");

Ответ 4

Кроме того, я бы посоветовал использовать strcpy или strcat, поскольку они могут привести к некоторым непредвиденным проблемам.

Используйте strncpy и strncat, поскольку они предотвращают переполнение буфера.

Ответ 5

Strcat добавляет строку в существующую строку. Если строковый массив пуст, он не будет набирать конец строки ('\0'), и это вызовет ошибку времени выполнения.

В соответствии с man-страницей Linux простой strcat реализован следующим образом:

   char*
   strncat(char *dest, const char *src, size_t n)
   {
       size_t dest_len = strlen(dest);
       size_t i;

       for (i = 0 ; i < n && src[i] != '\0' ; i++)
           dest[dest_len + i] = src[i];
       dest[dest_len + i] = '\0';

       return dest;
   }

Как вы можете видеть в этой реализации, strlen(dest) не вернет правильную длину строки, если только dest не инициализируется, чтобы исправить значения строки c. Вам может повезти иметь массив с первым значением нуля в char stuff[100];, но вы не должны полагаться на него.