Вы добавляете символ девяти (или более, gets
не имеющих границ) в строку с тремя символами (которая содержит четыре символа и без терминатора строк). Никакого прекращения строки. Поэтому, когда вы печатаете с использованием puts
, он будет продолжать печатать, пока не найдет символ окончания строки, который может быть в любом месте в памяти. Короче говоря, пример школьной книги переполнения буфера, а переполнение буфера обычно ведет к неопределенным поведением, что и есть то, что вы видите.
В C и C++ все строки в стиле C должны быть завершены. Они заканчиваются специальным символом: '\0'
(или простой ASCII-ноль). Вы также должны предоставить достаточно места для строки назначения в своем вызове strcat
.
Правильная, рабочая программа:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(void)
{
/* Size is 4 + 10 + 1, the last +1 for the string terminator */
char left[15] = "0000";
/* The initialization above sets the four first characters to '0'
* and properly terminates it by adding the (invisible) '\0' terminator
* which is included in the literal string.
*/
/* Space for ten characters, plus terminator */
char str[11];
/* Read string from user, with bounds-checking.
* Also check that something was truly read, as `fgets` returns
* `NULL` on error or other failure to read.
*/
if (fgets(str, sizeof(str), stdin) == NULL)
{
/* There might be an error */
if (ferror(stdin))
printf("Error reading input: %s\n", strerror(errno));
return 1;
}
/* Unfortunately `fgets` may leave the newline in the input string
* so we have to remove it.
* This is done by changing the newline to the string terminator.
*
* First check that the newline really is there though. This is done
* by first making sure there is something in the string (using `strlen`)
* and then to check if the last character is a newline. The use of `-1`
* is because strings like arrays starts their indexing at zero.
*/
if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
str[strlen(str) - 1] = '\0';
/* Here we know that `left` is currently four characters, and that `str`
* is at most ten characters (not including zero terminaton). Since the
* total length allocated for `left` is 15, we know that there is enough
* space in `left` to have `str` added to it.
*/
strcat(left, str);
/* Print the string */
printf("%s\n", left);
return 0;
}
Вы находитесь за пределами своего буфера. Это действительно неопределенное поведение. –
Функция [получает()] (http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) является устаревшей и опасной, дон Не используйте его. – this
left - это не строка с нулевым концом. Вам необходимо определить символ слева [5]; , а затем добавить после петли влево [4] = 0; // note 0, а не '0' –