Вы не показали ввод, который вы вводите в программу.
В вашей программе есть незначительные ошибки и некоторые существенные:
- Во-первых, вы были слишком резкимив распределении
char
массивов.Например, поле month
в структуре birthdate
содержит только 9 пробелов для хранения месяца, и это означает, что вы не можете хранить месяц, например september
, для которого требуется 9 символов плюс еще один для символа \0
nulв конце строки .Это может быть проблемой с вашим выполнением, если вы не будете осторожны. Это не распространенная практика - передавать struct
s напрямую по значению в функцию, так как это делаеткомпилятор для копирования всего содержимого структуры в стек параметров.Распространено передавать структуру по ссылке, как в
void printinfo(struct info *user);
, а затем вызывать ее как
printinfo(&user);
, что заставляет компилятор передавать только указатель на структуру, экономя времяи память.
Я не нашел функцию scanf_s
в своем руководстве онлайн, где вы ее взяли?Ну, после некоторого копания я нашел их ... из руководства VC для этих функций (не стандартно, просто расширение Microsoft):
В отличие от scanf и wscanf, scanf_s и wscanf_s требуют размер буфера, который должен быть указан для всех входных параметров типа c, C, s, S или наборов управления строк, которые заключены в [].Размер буфера в символах передается как дополнительный параметр, следующий сразу за указателем на буфер или переменную ...
, поэтому необходимо использовать
scanf_s("%s", &user.name, sizeof user.name - 1);
и то же самое для других строк, которые вы читаете.
NOTE
Эти суффиксированные функции _s
являются только расширениями Microsoft для их компилятора .Они не являются переносимыми (и в любом случае стандартными) и не появляются в большинстве реализаций Си.Лучше их не использовать, кроме случаев, когда вы собираетесь использовать только компиляторы Microsoft C (и вам не гарантируется, что они исчезнут в будущем).Есть и другие способы проверить размер буфера, кроме использования нестандартных функций, например
scanf("%.39s", user.name); /* there's no need to use the & operator here */
(если вам нужно передать размер в качестве параметра, вы можете сделать следующее):
SCANF("%.*s", sizeof user.name - 1, user.name);
выполнит работу, или
fgets(user.name, sizeof user.name, stdin);
(этот вызов требует, чтобы вы исключили последний \n
из строки) оба эти вызова являются стандартными, включены в <stdio.h>
.