Почему происходит неправильный вывод (либо "м" и "высшее", либо все наоборот "ж" и "среднее")?
Вывожу в консоль
void show (list cur) {
unsigned char k = 0;
system ("cls");
if (cur == NULL) {
puts ("Список пуст");
system("pause");
return;
}
puts ("| # | Фамилия | Год рождения | Пол | Образование | Год трудоустройства |");
puts ("-----------------------------------------------------------------------------------------------");
while (cur) {
printf ("| %-3d| %-30s| %-12d | %-3c | %-11s | %-19d |\n", ++k, cur->data.surname, cur->data.age, cur->data.gender == 1 ? 'м' : 'ж', cur->data.educ == 1 ? "высшее" : "среднее", cur->data.work);
cur = cur->next;
}
system("pause");
}
На выводе почему то все выводит "м" и "высшее", либо все наоборот "ж" и "среднее". Помогите, пожалуйста.
Ответы (1 шт):
Нужно смотреть на предупреждения компилятора - он предупреждает, что в scanf() вы передали формат для типа int, а аргумент типа short. И в результате, когда вы вводите год рождения scanf("%d", &emp.age), он перезатирает байты пола и образования. Т.к. scanf() получает адрес и записывает по этому адресу количество байт, которые вы указали в строке формата %d - это int а его размер - 4 байта (в общем случае).
struct employee {
char surname[30];
short age; // 2 байта
char gender; // 1 байт
char educ; // 1 байт
short work;
};
puts ("Год рождения");
while (scanf("%d", &emp.age) // %d записывает 4 байта, т.е. поверх age, gender, educ
// должно быть
scanf("%hd", &emp.age)
И та же самая ошибка при записи года трудоустройства.
При этом, год рождения затирает данные внутри объекта вашей структуры, а год трудоустройства - за пределами объекта что является неопределенным поведением - программа может рухнуть, а может работать и портить другие данные.
Вообще, чтобы не мучаться с приведением типов в строке формата scanf() вводите числа как целые во временную переменную, а потом просто присваивайте - приведение типов всё сделает правильно.
int tmp;
scanf("%d", &tmp)
emp.age = (short)tmp; // компилятор за вас сделает правильное приведение типа