В вашей программе 2 ошибки.
Во-первых, поймите, что значение «i» в вашем первом цикле всегда установлено на «индекс, в который мы будем записывать дальше».
i = 0; input = getchar();
while (input != '\n'){
my_stg2[i] = input;
++i;
input = getchar();
}
Выходя из этого цикла после написания «Hello!», Вы получите
my_stg2[] = {'H', 'e', 'l', 'l', 'o', '!'}, i=6
Когда вы начинаете читать значения из my_stg2, вы должны начать читать с (i-1), а не с i.
Вторая проблема заключается в том, что после копирования содержимого my_stg2 в my_stg вам необходимо выполнить:
my_stg2[j] = 0;
Это потому, что строки в C используют завершающий нуль для определения конца строки. Причина, по которой вы получаете символы мусора, следующие за вашей строкой на прикрепленной картинке, заключается в том, что код printf () будет продолжать печатать каждый последующий байт в памяти, пока он не достигнет 0, и вы никогда не поместите 0 в конце строки my_stg в явном виде.
В качестве альтернативы вы можете инициализировать все содержимое my_stg2 в 0 в начале вашей программы с помощью
memset(my_stg2, 0x00, sizeof(my_stg2));
Это важный урок с C - когда вы объявляете переменную, вам нужно инициализировать ее, или на некоторых платформах она будет заполнена тем, что ранее было сохранено в ячейке памяти.