For example in input.txt file there is date 20210405
. Date is in rrrrmmdd
format without any '/'
or '.'
. How do you check if date is in correct format not in 20211405
?.
My code works only for numbers that dont have zero in day for example 05
,07
,08
, my code works only for 10
or 11
. How do I fix that?
int main(){
char load[50];
long year, day, month;
int lenght, lenght2, lenght3;
int i = 0;
FILE* file;
file = fopen("input.txt", "r");
while (fgets(load, sizeof load, file) != NULL) {
if (i == 0) {
if (strlen(load) == 8) {
year = strtol(load, NULL, 10);
month = year;
day = year;
year = year * 0.0001;
lenght = (log10(abs(year))) 1;
if (lenght == 4) {
day = day % 100;
lenght2 = (log10(abs(day))) 1;
if (lenght2 == 2 && day <=31) {
month = (month % 10000)-30;
month = month / 100;
lenght3 = (log10(abs(day))) 1;
if (month <=12 && lenght2 == 2) {
printf("Datum: %s", load);
}
else {
printf("Invalid input.");
}
}
else {
printf("Invalid input.");
}
}
else {
printf("Invalid input.");
}
}
else {
printf("Invalid input.");
}
}
}
}
CodePudding user response:
You have a few flaws in your code:
fgets
includes a\n
at the end of your string if it is found in the file. Unless you read the last line where no more\n
is present, you will get 9 characters in your buffer.
Your conditionif (strlen(load) == 8)
will fail in the other cases.You should not use floating point operations on integers.
year = year * 0.0001;
In best case it is identical toyear = year / 10000;
, in worst case you get some rounding errors.You check the "length" of the value for
day
andmonth
by takinglog10
. That means that the numerical value must be >10 to get a length of 2. That is exactly what you are complaining about.
A proper check for valid valued would be to check whether the numerical value is in proper range.For some reason to reduce
month
by 30. That doesn't really make much sense.You don't use variable
i
at all. The correspondingif (i==0)
is rather useless.
A fixed version could look like this:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main(void) {
char load[50];
long year, day, month;
bool valid = false;
FILE* file = fopen("input.txt", "r");
// TODO: Check for NULL
while (fgets(load, sizeof load, file) != NULL) {
// Remove trailing '\n'
int len = strlen(load);
if (load[len-1] == '\n') {
load[len-1] = 0;
}
// Do we have exactly 8 digits?
if (strlen(load) == 8) {
long value = strtol(load, NULL, 10);
year = value / 10000;
month = (value / 100) % 100;
day = value % 100;
if (year >= 1000) {
if (day > 0 && day <= 31) {
if (month > 0 && month <= 12) {
valid = true;
}
}
}
}
if (valid) {
printf("Datum: %s", load);
}
else {
printf("Invalid input.");
}
}
}
}
CodePudding user response:
It is a bad idea to used floating point arithmetics to split the value into the year, month and day parts. The main reason for this is floating point numbers are represented internally in base 2 so 0.0001
is not represented exactly, so rounding the multiplication result truncate the value.
You should instead use integer arithmetics this way:
long value = strtol(load, NULL, 10);
year = value / 10000;
month = (value / 100) % 100;
day = value % 100;
You could also use `sscanf()