Home > Software design >  How do you check if date is in correct format
How do you check if date is in correct format

Time:11-07

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:

  1. 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 condition if (strlen(load) == 8) will fail in the other cases.

  2. You should not use floating point operations on integers.
    year = year * 0.0001; In best case it is identical to year = year / 10000;, in worst case you get some rounding errors.

  3. You check the "length" of the value for day and month by taking log10. 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.

  4. For some reason to reduce month by 30. That doesn't really make much sense.

  5. You don't use variable i at all. The corresponding if (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()

  •  Tags:  
  • c
  • Related