Hi I am confined to stdio.h, stdlib.h and string.h and I need to ask a user for input - the input can be any number of characters between 1 and 6, however the first two characters MUST be an uppercase alphabetical letter, and the remaining four characters MUST be a number between 0 and 9.
Examples of valid input:
Examples of Invalid Input:
Here is my attempt so far (just bear in mind I have almost no experience with C, the likelihood that this solution is "idiomatic" is next to none, and the reason I am asking this is so that I can learn):
Flightcode is a char array defined as flightcode[7]
it lives inside another struct called flight
. I am fgets
ing it into a temp_array[7]
first and then strcpy
ing it into the flight->flightcode such that the null terminator is appended and I don't know a better way of doing that.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FLIGHTCODE_LEN 6
#define MAX_CITYCODE_LEN 3
#define MAX_NUM_FLIGHTS 50
#define DB_NAME "database"
typedef struct {
int month;
int day;
int hour;
int minute;
} date_time_t;
typedef struct {
char flightcode[MAX_FLIGHTCODE_LEN + 1];
date_time_t departure_dt;
char arrival_city[MAX_CITYCODE_LEN + 1];
date_time_t arrival_dt;
} flight_t;
date_time_t departure_dt;
date_time_t arrival_dt;
char * scanline(char *dest, int dest_len);
int main(){
char temp_string[100];
flight_t flight[MAX_NUM_FLIGHTS + 1];
int correct_code = 0;
printf("Enter flight code>\n");
scanline(temp_string, sizeof(flight->flightcode));
strcpy(flight->flightcode, temp_string);
while(correct_code == 0)
{
for(int i = 0; flight->flightcode[i] != '\0' && correct_code == 0; i++)
{
while((i < 2 && (flight->flightcode[i] <= 64 || flight->flightcode[i] >= 91)) || (i > 1 && (flight->flightcode[i] < 48 || flight->flightcode[i] >= 58)))
{
printf("Invalid input.\n");
scanline(temp_string, sizeof(flight->flightcode));
strcpy(flight->flightcode, temp_string);
}
if((i < 2 && (flight->flightcode[i] > 64 || flight->flightcode[i] < 91)) || (i > 1 && (flight->flightcode[i] >= 48 || flight->flightcode[i] < 58)))
{
correct_code = 1;
}
}
}
}
char * scanline(char *dest, int dest_len){
int i, ch;
i = 0;
for (ch = getchar();
ch != '\n' && ch != EOF && i < dest_len -1; ch = getchar())
dest[i++] = ch;
dest[i] = '\0';
while (ch != '\n' && ch != EOF)
ch = getchar();
return (dest);
}
Scansets and the %n
specifier could be used to parse the input.
The format string "%n%2[A-Z]%n%4[0-9]%n"
uses the %n
specifier in three places to capture the number of characters processed. The scanset %2[A-Z]
will scan up to two characters if the characters are in the set of upper case letters. %4[0-9]
will scan up to four characters if the characters are digits.
If two values are scanned by sscanf
, the number of characters processed are subtracted to make sure there are two leading upper case characters and six or fewer total character and the trailing character is the terminating zero.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FLIGHTCODE_LEN 6
#define MAX_CITYCODE_LEN 3
#define MAX_NUM_FLIGHTS 50
#define DB_NAME "database"
typedef struct {
int month;
int day;
int hour;
int minute;
} date_time_t;
typedef struct {
char flightcode[MAX_FLIGHTCODE_LEN + 1];
date_time_t departure_dt;
char arrival_city[MAX_CITYCODE_LEN + 1];
date_time_t arrival_dt;
} flight_t;
date_time_t departure_dt;
date_time_t arrival_dt;
char * scanline(char *dest, int dest_len);
int main(){
int head = 0, leading = 0, tail = 0;
int correct_code = 0;
int result = 0;
char temp_string[100];
char upper[3] = "";
char digits[5] = "";
flight_t flight[MAX_NUM_FLIGHTS + 1];
do {
printf("Enter flight code>\n");
scanline(temp_string, sizeof(temp_string));
if ( 0 < ( result = sscanf ( temp_string, "%n%2[A-Z]%n%4[0-9]%n", &head, upper, &leading, digits, &tail))) {
if ( 1 == result && 0 == temp_string[leading]) {
correct_code = 1;
break;
}
if ( 2 == result && 2 == leading - head && 7 > tail - head && 0 == temp_string[tail]) {
correct_code = 1;
}
else {
printf ( "invalid input\n");
}
}
else {
printf ( "invalid input\n");
}
} while(correct_code == 0);
printf ( "Input is: %s\n", temp_string);
strcpy(flight->flightcode, temp_string);
return 0;
}
char * scanline(char *dest, int dest_len){
int i, ch;
i = 0;
for (ch = getchar(); ch != '\n' && ch != EOF && i < dest_len -1; ch = getchar()) {
dest[i++] = ch;
}
dest[i] = '\0';
while (ch != '\n' && ch != EOF) {
ch = getchar();
}
return dest;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With