Compiling:
gcc id_card_parser.c -o passport_data
Usage:
./passport_data $'IUUZBAD9876543210998877554433<\n9506229F7896543XXXUZB<<<<<<<<9\nESHMATOV<<TOSHMAT<<<<<<<<<<<<<'
| #include <stdio.h> | |
| #include <string.h> | |
| #include <ctype.h> | |
| #include <stdlib.h> | |
| int is_valid_passport_line(const char *line) { | |
| for (int i = 0; line[i]; i++) { | |
| if (!(isupper(line[i]) || isdigit(line[i]) || line[i] == '<')) { | |
| return 0; | |
| } | |
| } | |
| return 1; | |
| } | |
| int parse_dob_gender_country(const char *line2, char *dob, char *gender, char *countryCode) { | |
| if (strlen(line2) < 10) return 0; | |
| strncpy(dob, line2, 6); | |
| dob[6] = '\0'; | |
| *gender = line2[7]; | |
| strncpy(countryCode, line2 + 8, 3); | |
| countryCode[3] = '\0'; | |
| return 1; | |
| } | |
| void format_date(const char *dob, char *formattedDate) { | |
| int year = atoi((char[]){dob[0], dob[1], '\0'}); | |
| char fullYear[5]; | |
| if (year <= 21) { | |
| sprintf(fullYear, "20%02d", year); | |
| } else { | |
| sprintf(fullYear, "19%02d", year); | |
| } | |
| char month[3] = {dob[2], dob[3], '\0'}; | |
| char day[3] = {dob[4], dob[5], '\0'}; | |
| sprintf(formattedDate, "%s-%s-%s", fullYear, month, day); | |
| } | |
| int parse_name_line(const char *line3, char *lastName, char *firstName) { | |
| const char *sep = strstr(line3, "<<"); | |
| if (!sep) return 0; | |
| int lenLast = sep - line3; | |
| strncpy(lastName, line3, lenLast); | |
| lastName[lenLast] = '\0'; | |
| const char *firstStart = sep + 2; | |
| const char *end = strstr(firstStart, "<<"); | |
| if (!end) end = firstStart + strlen(firstStart); | |
| strncpy(firstName, firstStart, end - firstStart); | |
| firstName[end - firstStart] = '\0'; | |
| return 1; | |
| } | |
| int main(int argc, char *argv[]) { | |
| if (argc != 2) { | |
| printf("Usage: %s $'<passport_text_with_\\n_lines>'\n", argv[0]); | |
| return 1; | |
| } | |
| char *text = argv[1]; | |
| char *line1 = strtok(text, "\n"); | |
| char *line2 = strtok(NULL, "\n"); | |
| char *line3 = strtok(NULL, "\n"); | |
| if (!line1 || !line2 || !line3) { | |
| printf("Passport data should consist of exactly 3 lines.\n"); | |
| return 1; | |
| } | |
| if (!is_valid_passport_line(line1)) { | |
| printf("Invalid characters in the passport number (Line 1).\n"); | |
| return 1; | |
| } | |
| char dob[7], gender, countryCode[4]; | |
| if (!parse_dob_gender_country(line2, dob, &gender, countryCode)) { | |
| printf("Line 2 is not in the correct format (YYMMDD, gender, country code).\n"); | |
| return 1; | |
| } | |
| char formattedDate[11]; | |
| format_date(dob, formattedDate); | |
| char lastName[50], firstName[50]; | |
| if (!parse_name_line(line3, lastName, firstName)) { | |
| printf("Line 3 is not in the correct format (LastName<<FirstName).\n"); | |
| return 1; | |
| } | |
| printf("Passport Data:\n"); | |
| printf("Passport Number: %s\n", line1); | |
| printf("Date of Birth: %s\n", formattedDate); | |
| printf("Gender: %c\n", gender); | |
| printf("Country Code: %s\n", countryCode); | |
| printf("Last Name: %s\n", lastName); | |
| printf("First Name: %s\n", firstName); | |
| return 0; | |
| } |