В моем выводе отображаются странные символы

Мне пришлось кодировать для моего класса. Кодирование заключается в том, чтобы попросить пользователя ввести свое имя, возраст и идентификатор. Затем программа должна ввести код доступа, основанный на первых 6 буквах имени, возрасте и первых двух буквах студенческого билета. Проблема заключается в том, что на выходе появляется неопознанный символ (╠╠╠╠╠╠╠╠╠╠╠╠╠╠). Может кто-нибудь сказать мне, почему это там>? Затем он должен вычислить и отобразить длину пароля. Вот код:

#include <stdio.h>
#include <string.h>
void main(void)
{
char name[20], id[9], age[3], passcode[10];
int x;


puts("Enter your name:\n");
gets(name);

puts("\nEnter your student id:\n");
gets(id);

puts("\nEnter your age:\n");
gets(age);

x = strlen(passcode);

strncpy(passcode, name, 6);
strncat(passcode, id, 2);

printf("The passcode is:%s \n",passcode);
printf("The passcode has %d characters..\n",x);

}

И это выглядит так:

Enter your name:

johnny

Enter your student id:

dc87671

Enter your age:

20
The passcode is:johnny╠╠╠╠╠╠╠╠╠╠╠╠╠╠20dc
The passcode has 22 characters..
Press any key to continue . . .

person NewBie    schedule 21.01.2016    source источник
comment
Вы не должны использовать gets для чтения строки из стандартного ввода. Используйте такие функции, как fgets() или getline().   -  person Claudio Cortese    schedule 21.01.2016


Ответы (1)


Код доступа состоит из 22 символов.

И все же вы выделили буфер из 10 символов для пароля

passcode[10]

Вы не являетесь нулевым завершающим кодом доступа. Примечание от strncpy

Никакой нулевой символ неявно не добавляется в конце адресата, если источник длиннее num. Таким образом, в этом случае пункт назначения не должен считаться завершающейся нулем строкой C (чтение ее как таковой приведет к переполнению).

Обратите также внимание на то, что строка

x = strlen(passcode);

действует на пароль до его инициализации. Таким образом, он будет содержать случайные биты, что делает значение x нечетко определенным. В настоящее время вы не используете x, поэтому это не влияет на проблему напрямую.

person Eric J.    schedule 21.01.2016
comment
Рассмотрите возможность использования fgets вместо gets, поскольку в качестве параметра принимается максимальная длина - stackoverflow.com/questions/4346598 /gets-function-in-c - person Andrew Williamson; 21.01.2016
comment
@ericJ, так что мне делать, чтобы мой код заработал? - person NewBie; 21.01.2016
comment
Вам нужно добавить нулевой терминатор, например. пароль[6] = '\0' после копирования имени. Вам также необходимо обработать случай, когда имя содержит менее 6 цифр, например. Эрик. Вы можете дополнить более короткое имя пробелами или изменить 6 на min(strlen(name), 6); - person Eric J.; 21.01.2016