blidt
blidt

Reputation: 129

Reading date and hour with an specific format

I have been working on a program that reads a string which is supossed to be the date and the time with the following format dd-yy-aaaa hh:mm:ss. It does it n times, and at the end it prints the number of strings that were entered in the correct format. I haven't been able to make it only count the dates that have, for example, the year on a four digit format. It counts them as long as the data entered are numbers. How do i fix it? Here's my code

#include <stdio.h>

int main(){
    char string[100];
    int day[10];
    int month[10];
    int year[10];
    int hour[10];
    int minute[10];
    int second[10];
    int n,i=0;
    scanf("%d",&n);
    fflush(stdin);
    while(n!=0){
    scanf("%[^\n]s", &string);
    fflush(stdin);
        if((sscanf(string,"%d%d-%d%d-%d%d%d%d %d%d:%d%d:%d%d",day,month,year,hour,minute,second))==6){
        i++;
    }
    n--;
    }
    printf("%d",i);

}

Upvotes: 0

Views: 916

Answers (4)

chux
chux

Reputation: 154602

Use fgets() to read data and then parse using sscanf() features:
"%*1d%*1d" to detect 2 digits,
"%*1[ ]" to detect space
"%n" for the correct length and ending.

// 1 good, 0 bad
int CheckDate(const char *buffer) {
  static const char format[] = "dd-yy-aaaa hh:mm:ss\n";
  #define Space "%*1[ ]"
  #define Dig2 "%*1d%*1d"
  #define Dig4 Dig2 Dig2
  int n = 0;
  sscanf(buffer, Dig2 "-" Dig2 "-" Dig4 Space Dig2 ":" Dig2 ":" Dig2 "%n", &n);
  return (sizeof(format) - 2 == n) && (buffer[n] == '\n');
}

int main() {
  int i = 0;
  int n = 0;
  scanf("%d%*c", &n);
  while (n-- > 0) {
    char buffer[100];
    if (fgets(buffer, sizeof buffer, stdin) == NULL) break; // EOF
    i += CheckDate(buffer);
  }
  printf("%d",i);
  return 0;
}

Upvotes: 0

BLUEPIXY
BLUEPIXY

Reputation: 40155

e.g. to fix

char string[100];
int day;
int month;
int year;
int hour;
int minute;
int second;
int n,i=0;
scanf("%d", &n);
fflush(stdin);//non-portable
while(n>0){
    scanf(" %99[^\n]", &string);
    fflush(stdin);
    if((sscanf(string,"%2d-%2d-%4d %2d:%2d:%2d", &day,&month,&year,&hour,&minute,&second))==6){
        //range check
        ++i;
    }
    --n;
}
printf("%d", i);

Upvotes: 1

kbshimmyo
kbshimmyo

Reputation: 579

A few notes to clarify:

  1. Why are day etc. arrays of length 10? Do you expect n <= 10 and to save each date?

  2. You need a return statement.

  3. Is i supposed to be the number of successfully parsed dates?

Ok, so there are some problems with the way you're using sscanf (but yay for checking the return value!) - here's the specification.

  1. sscanf must have the address to which you want to read the input - so &day[i] presumably.

  2. %d will read the whole int, not just one digit - that is,

      sscanf(string, "%d", &my_int_var);
    

will read the first int it encounters, whether that be 1, 10, 1987, 2008875, etc.

Upvotes: 1

abligh
abligh

Reputation: 25219

You will make your life a lot easier if you use strptime, i.e.:

From the manpage:

NAME

  strptime - convert a string representation of time to a time tm structure

SYNOPSIS

  #define _XOPEN_SOURCE       /* See feature_test_macros(7) */
  #include <time.h>

  char *strptime(const char *s, const char *format, struct tm *tm);

DESCRIPTION

The strptime() function is the converse function to strftime(3) and converts the character string pointed to by s to values which are stored in the tm structure pointed to by tm, using the format specified by format. Here format is a character string that consists of field descriptors and text characters, reminiscent of scanf(3). Each field descriptor consists of a % character followed by another character that specifies the replacement for the field descriptor. All other characters in the format string must have a matching character in the input string, except for whitespace, which matches zero or more whitespace characters in the input string. There should be whitespace or other alphanumeric characters between any two field descriptors.

And so it continues ...

Upvotes: 2

Related Questions