C/C++

Язык Си. Тема: структуры данных.

Необходимо произвести ввод и вывод массива структур на экран. Структура «Клиент банка» включает в себя: Фамилия И. О. самого клиента, номер счёта, сумма на счёте, дата последнего изменения. Необходима помощь с доработкой ввода, чтобы он стал более фиксированным (например, я могу ввести дату 25.01.2021 или 25 января 2021-го года, а мне нужно вводить именно первым вариантом (25.01.2021) - как это сделать?), та же ситуация с вводом ФИО - написал, например, фамилию, имя, потом отчество и после него пару цифр - и программа одобрила. Помогите, пожалуйста, разобраться в коде. Ну, с датой я думал, что можно в структуры 3 int-a ввести (day, month и year соответственно), а потом вводить их с помощью цикла while (scanf_s("%lf", &a[i].process.day) == 0 || a[i].process.day < 0 || prov(a[i].process.day) == 1), а в printf-e выводить дату через точки, а на ввод ФИО надо писать какое-то ограничивающее условие. Первое что пришло в голову, это ограничить, опять же: while (a[i].process.master>='a' && a[i].process.master <='Z') и так же для русского алфавита - только как потом возвразать пользователя на повторный ввод сначала? Кто может, подскажите, буду благодарен.

Непосредственно сам код доступен по ссылке:

https://ideone.com/2Z26YK
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
_Bool is_leap(int year) {
bool result = true;
if (year % 4 != 0) result = false;
else if (0 == year % 400) result = true;
else if (0 == year % 100) result = false;
return result;
}
_Bool mask_date(char* date) {
static int month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int i = 0, d, m, y;
if (strlen(date) != 10) return false;
do {
if (date[i] < 0) return false;
if (!isdigit(date[i]) && date[i] != '.') return false;
if ((i == 2 || i == 5) && date[i] != '.') return false;
} while (date[++i]);
d = atoi(date);
if (!d || d > 31) return false;
m = atoi(date + 3);
if (!m || m > 12) return false;
y = atoi(date + 6);
if (y < 1900 || y > 9999) return false;
if (m == 2 && is_leap(y)) return d <= 29;
return d <= month[m];
}
int main(void) {
char date[11];
_Bool flag_error = false;
system("chcp 1251 > nul");
do {
if (flag_error) puts("Ошибка!");
printf("Введите дату в формате dd.mm.yyyy: ");
scanf_s("%s", date, _countof(date));
if (!flag_error) flag_error = true;
} while (!mask_date(date));
system("pause");
}
Дмитрий Дроздов
Дмитрий Дроздов
68 979
Лучший ответ
Чтобы написать нормальную логику работы этой программы, нужно сперва детально продумать структуру, в которую сохраняешь данные.
Дату нужно действительно разнести по целочисленным полям. Она так и хранится в struct tm в time.h.
ФИО нужно разнести по полям, состоящим из массивов char, например:
char FirstName[25];
char Name[25];
char LastName[25]; Тогда и ввод данных уже будет полегче организован.
Старайся писать стандартными операторами и функциями, без ненужных примочек Виндовс, типа scanf_s, printf_s, windows.h и т. п.
Стандартная библиотека языка Си позволяет делать многое. А здесь задача не сложная. Из-за ненужных фичей только писанины стало больше и текст менее читабельный.