我正在为一个类开发一个程序,这就是我目前所拥有的。我的朋友帮助我完成了这个功能,但是当输入错误的日期时,它应该迭代,直到询问正确的日期。不知道该怎么做,我们已经为此工作了几个小时,因为我们都是 C 的新手,我们需要一些外部帮助。
#include <stdio.h> //for input output
#include <stdlib.h>
#include <string.h> // for string functions
#include <time.h> //for time functions
#include <stdbool.h> //bool functions for true/false
//used typedef for convenience, no need to type struct all the time
typedef struct
{
int m, d, y;
} Data_t;
int checkDate (int m, int d, int y); //declare function to check input
void modDate (Data_t * data); //declare function to modify date
int
main ()
{
int x = 0; //kill switch for while loop
//declare a struct variable and initialize it for the date
Data_t uDate = { 0, 0, 0 };
/* program has infinite loop bug when using the while loop with x */
while (x == 0){
printf ("x before input: %dn", x); //debug printer
// Ask user for date input
printf ("Enter a date in mm/dd/yyyy format: ");
//Pass the input to the uDate struct with scanf
scanf ("%d/%d/%d", &uDate.m, &uDate.d, &uDate.y);
// check data if valid and set x
x = checkDate (uDate.m, uDate.d, uDate.y);
printf ("x after check: %dn", x); //debug printer
}
// end of while loop
// Display the entered date & modifier message
printf ("nDate Entered: %d/%d/%dn", uDate.m, uDate.d, uDate.y);
printf ("Adding 1 week to entered date...n");
modDate (&uDate); //pass the address of uDate to the modDate function
/* since it was passed through a pointer (by reference),
the original uDate struct is now modified */
// Display the modified date
printf ("New Date is: %d/%d/%dn", uDate.m, uDate.d, uDate.y);
return 0;
}
//Define the checkDate function
int
checkDate (int m, int d, int y)
{
// This is sloppy. Clean it up with multiple functions later
if (y <= 0)
{
printf ("Invalid Date, Please try again.n");
return false;
}
if (m >= 1 && m <= 12)
{
//Then check the days against the months & leap years
if ((d >= 1 && d <= 31)
&& (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10
|| m == 12))
{
return true;
}
else if ((d >= 1 && d <= 30) && (m == 4 || m == 6 || m == 9 || m == 11))
{
return true;
}
else if ((d >= 1 && d <= 28) && (m == 2))
{
return true;
}
else if (d == 29 && m == 2
&& (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)))
{
return true;
}
else
{
printf ("Invalid Date, Please try again.n");
return false;
}
}
else
{
printf ("Invalid Date, Please try again.n");
return false;
}
}
//Define the modDate function to add 7 days
void
modDate (Data_t * data)
{
data->d = data->d + 7; // modify the day element in struct
// initialize the time_t structs from time.h and pass elements
struct tm t = {.tm_mon = data->m - 1,.tm_mday = data->d,
.tm_year = data->y - 1900
};
/* month+/-1 is because tm struct stores january as 0 and december as 11
year+/- 1900 is because year values are calculated starting from
the year 1900. So when calculating with mktime() you need to get
the integer value of the year by y-1900. And to properly display
the year value that is returned, you add 1900 as done below */
mktime (&t); // call mktime() to calculate the new date
// pass new values into struct and reformat month & year
data->m = t.tm_mon + 1;
data->d = t.tm_mday;
data->y = t.tm_year + 1900;
}
您的问题是 scanf 的错误输入没有得到正确处理。
如果输入类似"A"
的内容,scanf ("%d/%d/%d", &uDate.m, &uDate.d, &uDate.y);
将不会成功,因为它无法读取预期的任何int
。 由于"A"
未正确处理,因此它仍保留在输入缓冲区中,这将导致scanf
一次又一次地失败。
因此,首先您应该检查是否读取了所有 3 个预期值:
if (scanf ("%d/%d/%d", &uDate.m, &uDate.d, &uDate.y) != 3)
// x remains 0
printf("Invalid input format!n");
else
x = checkDate (uDate.m, uDate.d, uDate.y);
仅此还不够,因为错误的输入仍保留在输入缓冲区中。因此,您需要在下次尝试之前刷新它:
编辑正如@AndrewHenle指出的那样,您应该避免使用fflush(stdin)
(至少如果您不在Windows平台上并希望保持代码可移植性(。 因此,另一种解决方案是读取每个输入,包括用户输入后的换行符,例如while((getchar()) != 'n');
if (scanf ("%d/%d/%d", &uDate.m, &uDate.d, &uDate.y) != 3)
// x remains 0
printf("Invalid input format!n");
else
x = checkDate (uDate.m, uDate.d, uDate.y);
// flush input buffer
while((getchar()) != 'n');
您已将int checkDate (int m, int d, int y);
的返回类型声明为int
但返回bool
。当更正此问题以bool checkDate (int m, int d, int y);
代码似乎有效时:
#include <stdio.h> //for input output
#include <stdlib.h>
#include <string.h> // for string functions
#include <time.h> //for time functions
#include <stdbool.h> //bool functions for true/false
//used typedef for convenience, no need to type struct all the time
typedef struct
{
int m, d, y;
} Data_t;
bool checkDate (int m, int d, int y); //declare function to check input
void modDate (Data_t * data); //declare function to modify date
int
main ()
{
bool x = false; //kill switch for while loop
//declare a struct variable and initialize it for the date
Data_t uDate = { 0, 0, 0 };
/* program has infinite loop bug when using the while loop with x */
while (x == false){
printf ("x before input: %dn", x); //debug printer
// Ask user for date input
printf ("Enter a date in mm/dd/yyyy format: ");
//Pass the input to the uDate struct with scanf
scanf ("%d/%d/%d", &uDate.m, &uDate.d, &uDate.y);
// check data if valid and set x
x = checkDate (uDate.m, uDate.d, uDate.y);
printf ("x after check: %dn", x); //debug printer
}
// end of while loop
// Display the entered date & modifier message
printf ("nDate Entered: %d/%d/%dn", uDate.m, uDate.d, uDate.y);
printf ("Adding 1 week to entered date...n");
modDate (&uDate); //pass the address of uDate to the modDate function
/* since it was passed through a pointer (by reference),
the original uDate struct is now modified */
// Display the modified date
printf ("New Date is: %d/%d/%dn", uDate.m, uDate.d, uDate.y);
return 0;
}
//Define the checkDate function
bool
checkDate (int m, int d, int y)
{
// This is sloppy. Clean it up with multiple functions later
if (y <= 0)
{
printf ("Invalid Date, Please try again.n");
return false;
}
if (m >= 1 && m <= 12)
{
//Then check the days against the months & leap years
if ((d >= 1 && d <= 31)
&& (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10
|| m == 12))
{
return true;
}
else if ((d >= 1 && d <= 30) && (m == 4 || m == 6 || m == 9 || m == 11))
{
return true;
}
else if ((d >= 1 && d <= 28) && (m == 2))
{
return true;
}
else if (d == 29 && m == 2
&& (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)))
{
return true;
}
else
{
printf ("Invalid Date, Please try again.n");
return false;
}
}
else
{
printf ("Invalid Date, Please try again.n");
return false;
}
}
//Define the modDate function to add 7 days
void
modDate (Data_t * data)
{
data->d = data->d + 7; // modify the day element in struct
// initialize the time_t structs from time.h and pass elements
struct tm t = {.tm_mon = data->m - 1,.tm_mday = data->d,
.tm_year = data->y - 1900
};
/* month+/-1 is because tm struct stores january as 0 and december as 11
year+/- 1900 is because year values are calculated starting from
the year 1900. So when calculating with mktime() you need to get
the integer value of the year by y-1900. And to properly display
the year value that is returned, you add 1900 as done below */
mktime (&t); // call mktime() to calculate the new date
// pass new values into struct and reformat month & year
data->m = t.tm_mon + 1;
data->d = t.tm_mday;
data->y = t.tm_year + 1900;
}