C++ - Kontrollera formatet på en sträng.

Permalänk
Medlem

C++ - Kontrollera formatet på en sträng.

Tjena,

När jag matar in en datumsträng vill jag kolla att den har rätt format. Om jag matar in 2012-03-04 så vill jag jämföra den mot en mall, typ xxx-xx-xx där varje x är en siffra. Om sen testet returnerar false vill jag skriva ut "Fel format". Går detta att göra på något enkelt sätt? Har googlat en hel del men alla andra vill bara jämföra två olika datumsträngar för att se vilken som är nyast/äldst.

Tack!

Visa signatur

Rigg: ASUS ROG Strix B660-I Gaming WIFI | i5 12400F | Corsair Vengence DDR5, 32 GB | nVidia Geforce GTX 1060 3GB | Samsung 980 PRO, 1 TB

Permalänk
Medlem

borde ju gå att göra så att man skriver in 3 olika variabler.
typ year-month-day
också när man inputar ett datum så får variablerna varsit värde och om month större än 12 error, day större än 31 error.
day får man kanske göra en switch på month, iom att dagarna i en månad är olika. så om month = 1 får inte day vara större än 31 och om month = 2 får inte day vara större än 28 if ((year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) day inte större än 29.
(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) är för att kolla om year är skottår

Visa signatur

i5 3570k / Asus p8z77-i Deluxe / Asus Gtx680 DCII / Corsair Ax 750w / Ocz Petrol 256GB / Corsair Vengeance 16GB

Permalänk
Medlem

Jag skulle definitivt använda regex för detta. Google is your friend.

Skickades från m.sweclockers.com

Permalänk
Datavetare

Du kan ju försöka beskriva den syntax du vill läsa in, om vi börjar med hela datumet så är detta

<date> ::= <year> '-' <month> '-' <day>

sedan är det bara att beskriva year, month och day

<year> ::= <digit> <digit> <digit> <digit> <month> ::= <digit> <digit> <day> ::= <digit> <digit>

och slutligen behöver du en definition av digit

<digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

Problemet är nu reducerat till att läsa in tecknen -0123456789 samt eventuellt lägga restriktioner på värdet på år, månad och dag.

En relativt direkt översättning av denna syntax till C skulle kunna se ut t.ex. så här

#include <stdlib.h> #include <stdio.h> int ipow10(int e) { if (e == 0) return 1; return 10 * ipow10(e - 1); } const char *parse_digit(const char *str, int *digit) { if (str == NULL || *str < '0' || *str > '9') return NULL; *digit = *str - '0'; return str + 1; } const char *parse_number(const char *str, int *n, int cnt) { int d; const char *rest = str; *n = 0; for (int i = 1; i <= cnt; i++) { rest = parse_digit(rest, &d); *n += d * ipow10(cnt - i); } return rest; } const char *parse_year(const char *str, int *year) { return parse_number(str, year, 4); } const char *parse_month(const char *str, int *month) { return parse_number(str, month, 2); } const char *parse_day(const char *str, int *day) { return parse_number(str, day, 2); } const char *parse_tkn(const char *str, char tkn) { if (str && *str == tkn) return str + 1; return NULL; } const char *parse_date(const char *str, int *year, int *month, int *day) { const char *rest; rest = parse_year(str, year); rest = parse_tkn(rest, '-'); rest = parse_month(rest, month); rest = parse_tkn(rest, '-'); return parse_day(rest, day); } int main(int argc, char *argv[]) { int year; int month; int day; if (argc != 2) { fprintf(stderr, "Usage: %s <date-string>\n", argv[0]); return EXIT_FAILURE; } if (!parse_date(argv[1], &year, &month, &day)) { fprintf(stderr, "%s is not a valid date in format yyyy-mm-dd\n", argv[1]); return EXIT_FAILURE; } printf("Year : %d\nMonth : %d\nDay : %d\n", year, month, day); return EXIT_SUCCESS; }

Dold text

Vill du ha gränser på vilka värden som är ok på år, månad och dag så är det bara att lägga till det i respektive parse_xxx funktion. Samma sak gäller om du vill acceptera både 2013-02-20 och 2013-2-20, bara att uppdatera syntaxen för vad som är giltig syntax för månad.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem

Du kan antagligen använda "regex", eller om du vill förstå vad som händer göra som "virtual void" beskriver väldigt utförligt och bra.