确保scanf仅读取dd.mm.yyyy
我正在寻找解决我问题的办法。 我想扫描一个日期(dd.mm.yyyy)。我需要确保,输入的格式只有0<天<31;0<13个月;2018年 对于任务的长度,我是这样做的:确保scanf仅读取dd.mm.yyyy,c,C,我正在寻找解决我问题的办法。 我想扫描一个日期(dd.mm.yyyy)。我需要确保,输入的格式只有0name,what);strcpy(temp->deadline,when);strcpy(temp->place,where);temp->next=pointer;`但我不能用3个整数来做这件事。'我必须把日期放在那之后'是什么意思?你现在是否也可以使用fgets而不是scanf,特别是因为这样可以防止缓冲区溢出
printf("Please typ in the Task: \t");
scanf("%s", &what);
while (strlen(what) >= MAX) {
clearScanf();
printf("The task must contain a maximum of %d :\t", MAX - 1);
scanf("%s", &what);
}
但我不知道如何确保我的
printf("Pls put in the Deadline (dd.mm.yyyy): \t");
scanf("%s", when);
不会接受字符,但仍在字符之间使用“.”
在scanf之后,我想通过以下方式将我的结构的一切都归还给我:
strcpy(temp->name, what);
strcpy(temp->deadline, when);
temp->next = pointer;
但是我不知道,如何将月、年、日分开还给你。使用
scanf
+sscanf
:
int day, month, year;
for(;;) /* Infinite loop */
{
scanf("%s", when);
char temp;
if(sscanf(when, "%2d.%2d.%4d%c", &day, &month, &year, &temp) != 4 ||
temp != '\n') /* Check if no extra characters were typed after the date */
{
fputs("Invalid format!\n", stderr);
clearScanf(); /* Assuming this function of yours clears the stdin */
}
else if(!(0 < date && date <= 31) || /* Valid range checks */
!(0 < month && month <= 12) ||
!(0 < year && year <= 2018))
{
fputs("Invalid date!\n", stderr);
}
else
{
break;
}
}
int日、月、年;
对于(;)/*无限循环*/
{
scanf(“%s”,何时);
焦炭温度;
如果(sscanf(当“%2d.%2d.%4d%c”、&日、月、年和温度)!=4||
temp!='\n')/*检查日期后是否键入了额外字符*/
{
fputs(“无效格式!\n”,标准格式);
clearcanf();/*假设您的此函数清除stdin*/
}
如果(!(0scanf
+sscanf
:
int day, month, year;
for(;;) /* Infinite loop */
{
scanf("%s", when);
char temp;
if(sscanf(when, "%2d.%2d.%4d%c", &day, &month, &year, &temp) != 4 ||
temp != '\n') /* Check if no extra characters were typed after the date */
{
fputs("Invalid format!\n", stderr);
clearScanf(); /* Assuming this function of yours clears the stdin */
}
else if(!(0 < date && date <= 31) || /* Valid range checks */
!(0 < month && month <= 12) ||
!(0 < year && year <= 2018))
{
fputs("Invalid date!\n", stderr);
}
else
{
break;
}
}
int日、月、年;
对于(;)/*无限循环*/
{
scanf(“%s”,何时);
焦炭温度;
如果(sscanf(当“%2d.%2d.%4d%c”、&日、月、年和温度)!=4||
temp!='\n')/*检查日期后是否键入了额外字符*/
{
fputs(“无效格式!\n”,标准格式);
clearcanf();/*假设您的此函数清除stdin*/
}
否则如果(!(0
bool is_correctly_formatted(const char* s) {
if(!isdigit(s[0])) return false;
if(!isdigit(s[1])) return false;
if('.' != s[2]) return false;
if(!isdigit(s[3])) return false;
if(!isdigit(s[4])) return false;
if('.' != s[5]) return false;
if(!isdigit(s[6])) return false;
if(!isdigit(s[7])) return false;
if(0 != s[8]) return false;
return true;
}
然后,您可以像这样使用它:
#define MAX 8
int main(int argc, char** argv) {
/* Space for MAX chars + line feed + terminal zero */
char what[MAX + 1 + 1] = {0};
/* Ensure that scanf reads in at most as many chars as can be safely written to `what` */
char format[MAX + 2 + 1] = {0};
snprintf(format, sizeof(format), "%%%ds", MAX + 1);
do {
printf("%s Please type in the Task: ", format);
scanf(format, &what[0]);
/* chomp the trailing '\n' */
if(isspace(what[MAX + 1])) what[MAX + 1] = 0;
printf("Entered %s\n", what);
} while (! is_correctly_formatted(what));
}
这使你能够在你期望的事情上尽可能地灵活。你甚至可以求助于使用某种方法
注意:读取字符串将包含尾随换行符,因此您必须删除它…编写您自己的格式检查函数:
bool is_correctly_formatted(const char* s) {
if(!isdigit(s[0])) return false;
if(!isdigit(s[1])) return false;
if('.' != s[2]) return false;
if(!isdigit(s[3])) return false;
if(!isdigit(s[4])) return false;
if('.' != s[5]) return false;
if(!isdigit(s[6])) return false;
if(!isdigit(s[7])) return false;
if(0 != s[8]) return false;
return true;
}
然后,您可以像这样使用它:
#define MAX 8
int main(int argc, char** argv) {
/* Space for MAX chars + line feed + terminal zero */
char what[MAX + 1 + 1] = {0};
/* Ensure that scanf reads in at most as many chars as can be safely written to `what` */
char format[MAX + 2 + 1] = {0};
snprintf(format, sizeof(format), "%%%ds", MAX + 1);
do {
printf("%s Please type in the Task: ", format);
scanf(format, &what[0]);
/* chomp the trailing '\n' */
if(isspace(what[MAX + 1])) what[MAX + 1] = 0;
printf("Entered %s\n", what);
} while (! is_correctly_formatted(what));
}
这使你能够在你期望的事情上尽可能地灵活。你甚至可以求助于使用某种方法
注意:读取的字符串将包含尾随换行符,因此您必须将其删除…仅使用scanf
无法做到这一点。您需要手动解析字符串,在无法解析输入时返回错误。仅使用scanf
无法做到这一点。您需要手动解析字符串,在可以时返回错误“我无法分析输入。警告:scanf
家族对它所接受的内容非常松散。如果我没记错的话,它也会接受像3.4.-53
(我还没有测试过)这样的日期。”虽然这是我最初的想法,但如果用户输入,这将失败,例如,19.08.2522
?好的,我需要将日期放在后面。现在,我这样做:'strcpy(temp->name,what);strcpy(temp->deadline,when);strcpy(temp->place,where);temp->next=pointer;`但是我不能用3个整数来做这件事。'我必须把日期放在那之后'是什么意思?你现在也可以使用fgets
而不是scanf
,特别是因为这样可以防止缓冲区溢出警告:scanf
家族对它所接受的内容非常松散。如果我记得corre实际上,这也会接受像3.4.-53这样的日期(虽然我还没有测试),虽然这是我最初的想法,但如果用户输入,这将失败,例如,19.08.2522
?好的,我需要把日期放在后面。现在,我这样做:'strcpy(temp->name,what);strcpy(temp->deadline,when);strcpy(temp->place,where);temp->next=pointer;`但我不能用3个整数来做这件事。'我必须把日期放在那之后'是什么意思?你现在是否也可以使用fgets
而不是scanf
,特别是因为这样可以防止缓冲区溢出