Reputation: 129
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
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
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
Reputation: 579
A few notes to clarify:
Why are day
etc. arrays of length 10? Do you expect n <= 10
and to save each date?
You need a return
statement.
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.
sscanf
must have the address to which you want to read the input - so &day[i]
presumably.
%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
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 tostrftime
(3) and converts the character string pointed to bys
to values which are stored in the tm structure pointed to bytm
, using the format specified byformat
. Hereformat
is a character string that consists of field descriptors and text characters, reminiscent ofscanf(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