Reputation: 3
I need to read hours:minutes in this exact format. I use:
int hours, minutes;
if (scanf("%d:%d", &hours, &minutes)!= 2)
{
printf("Wrong input.\n");
return 1;
}
else if (minutes>60 || minutes<0 || hours<0)
{
printf("Wrong input.\n");
return 1;
}
time = hours*60 + minutes;
/*read another time interval */
if (scanf("%d:%d", &hours, &minutes)!= 2)
{
printf("Wrong input 2.\n");
return 1;
}
else if (minutes>60 || minutes<0 || hours<0)
{
printf("Wrong input 2.\n");
return 1;
}
...
works fine, but I need to get "wrong input" also in situations that someone enters e.g. 5:38abc
Upvotes: 0
Views: 176
Reputation: 1
The traditional way is to read an entire line using getline(3) or fgets(3) (so the line is in a buffer), then to parse that line. You could use sscanf(3) - perhaps with its %n
specifier - or you could parse that line more manually with e.g. strtol(3) (which sets the end pointer).
So something like:
int endpos= -1;
char linbuf[32];
memset(linbuf, 0, sizeof(linbuf));
if (!fgets(linbuf, sizeof(linbuf)) exit(EXIT_FAILURE);
if (sscanf(linbuf, "%O2d:%02d%n", &hour, &minute, &endpos)<2)
exit(EXIT_FAILURE);
if (endpos!=6) exit(EXIT_FAILURE);
if (hour<0 || minute<0 || hour>=24 || minute>=60) exit(EXIT_FAILURE);
Of course you would replace the exit(EXIT_FAILURE);
with a more user-friendly rejection.
BTW, you should specify if 1:2
is acceptable input or if you require 01:02
. And would you accept an empty line as representing noon?
Upvotes: 0
Reputation: 780818
Add an operator to the format string to match the newline:
int hours, minutes;
char str[2];
if (scanf("%d:%d%1[\n]", &hours, &minutes, str)!= 3)
%[\n]
matches newline characters, and the field width 1
makes it stop matching after exactly 1 character.
Upvotes: 1