我将以下日期作为用户输入的某个日期:mm / dd / yyyy。
如何确定用户仅输入数字值,如果不是,则再次提示他输入有效日期。我已经在根据输入的值检查日期是否有效,但是如果用户输入的值不完全是数字,则程序崩溃。
请帮忙...
代码:
int x=0;
printf("\nEnter the date of birth(mm/dd/yyyy):");
do
{
scanf("%d/%d/%d",&add.dob.month,&add.dob.day,&add.dob.year);
if((add.dob.month<13 && add.dob.month>0) && (add.dob.day>0 && add.dob.day<32) && (add.dob.year<2016))
{
x=1;
}
else
{
printf("\nThe above date of birth is invalid.\nEnter a valid date of birth(mm/dd/yyyy):");
}
}while(x!=1);
有几个问题。如果使用,scanf
请检查其返回值。除了数字有效性检查外,如果用户输入的不是整数,还可能需要刷新输入缓冲区。尽管有多种方法可以执行此操作,但一种与您的方法保持一致的方法只是简单地执行正在执行的检查,然后使用第二个do/while
循环手动刷新输入缓冲区。您还可以改变逻辑并测试是否有任何一个真实的条件,迫使另一个提示输入日期。如上所述,有许多方法可以解决此问题。将此视为您收到的其他答案之一。
int c = 0; /* value to test for end of input buffer */
printf("\nEnter the date of birth(mm/dd/yyyy):");
while ((scanf("%d/%d/%d",&add.dob.month,&add.dob.day,&add.dob.year) != 3) ||
(add.dob.month < 1) ||
(add.dob.month > 12 ) ||
(add.dob.day < 1 ) ||
(add.dob.day > 31) ||
(add.dob.year < 1) ||
(add.dob.year > 2015))
{
printf("\nThe above date of birth is invalid.\nEnter a valid date of birth(mm/dd/yyyy):");
do { c = getchar(); } while (c != '\n' && c != EOF); /* flush input buffer */
}
如前所述,从中读取信息的一种更可靠的方法stdin
是使用fgets
或将日期作为字符串读取到缓冲区中getline
,然后从缓冲区中解析月,日,年信息。这也可以通过许多方式来完成。由于您最终将要从字符转换为十进制,因此也可以只使用strtol
解析和转换,而不是使用指针降低字符串或使用strtok
或进行解析strsep
(因为每个字符都需要在分离后转换为十进制)。这是一个快速的示例,提供了相当强大的解决方案。它还允许在以下日期mm-dd-yyyy
或mm.dd.yyy
之外输入日期mm/dd/yyyy
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#define SZDATE 12
int main (void) {
int mm = 0; // month/day/year values
int dd = 0;
int yyyy = 0;
int gooddate = 0; // flag signifying valid date
char datestr[SZDATE] = {0}; // buffer to hold input string
char *p = NULL; // pointer to use with strtol
char *endptr = NULL; // end pointer for strtol
long val = 0; // long value for strtol
while (gooddate == 0)
{
printf("\nEnter the date of birth (mm/dd/yyyy): ");
/* read string with fgets */
fgets (datestr, SZDATE-1, stdin);
/* test sufficient length */
if (strlen (datestr) < 8) {
printf ("\n insufficient date length entered, try again.\n");
continue;
}
/* parse month value with strtol (with error checking) */
errno = 0;
val = strtol (datestr, &endptr, 10);
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
|| (errno != 0 && val == 0)
|| (endptr == datestr)
|| (*endptr != '/' && *endptr != '-' && *endptr != '.')
|| (val < 1)
|| (val > 12)) {
printf ("\n invalid month entered, try again.\n");
continue;
}
mm = (int) val; /* set month on successful conversion */
p = ++endptr; /* set p to start of day, reset endptr */
endptr = NULL;
/* parse day value with strtol (with error checking) */
errno = 0;
val = strtol (p, &endptr, 10);
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
|| (errno != 0 && val == 0)
|| (endptr == p)
|| (*endptr != '/' && *endptr != '-' && *endptr != '.')
|| (val < 1)
|| (val > 31)) {
printf ("\n invalid day entered, try again.\n");
continue;
}
dd = (int) val; /* set day on successful conversion */
p = ++endptr; /* set p to start of year, reset endptr */
endptr = NULL;
/* parse year value with strtol (with error checking) */
errno = 0;
val = strtol (p, &endptr, 10);
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
|| (errno != 0 && val == 0)
|| (endptr == p)
|| (*endptr != '\n' && *endptr != 0)
|| (val < 1900)
|| (val > 2015)) {
printf ("\n invalid year entered, try again.\n");
continue;
}
yyyy = (int) val; /* set year on successful conversion */
gooddate = 1; /* set gooddate flag ending loop */
}
printf ("\n valid date is: %d/%d/%d\n\n", mm, dd, yyyy);
return 0;
}
考虑与strtol
转换相关的检查。您可能想要添加更多。另外,请尝试使用strtok
或类似内容进行分析并进行比较。这只是将读为字符串然后进行解析的一种方式。它可以通过许多不同的方式来完成。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句