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; | |
} |