所以我刚开始学习结构,我最近的问题要求我检查用户输入的屏幕时间,唯一有效的范围是下午2点,下午5点,晚上8点和晚上11点。我为它做了一个很长的屁股代码并按预期工作,但我不认为它是有效的?我尝试为有效屏幕时间创建一个数组,并在4号数组中输入所有4个值,并在用户输入他们的选择时进行循环检查数组中的每个值,但是当用户输入错误选项时,它会显示4条错误消息因为它检查数组中的所有4个值,所以它是错误的。无论如何,这是我的代码:
void main(){
typedef struct{
char movieName[20];
int screenTime;
float price;
int seatNum;
} MovieTicket;
MovieTicket ticket;
//int validTime[4] = {2, 5, 8, 11};
do{
printf("Enter your screen time: ");
scanf("%d", &ticket.screenTime);
if(ticket.screenTime != 2 && ticket.screenTime != 5 && ticket.screenTime != 8 && ticket.screenTime != 11){
printf("Invalid Screen Time! Enter again please!\n");
}
} while(ticket.screenTime != 2 && ticket.screenTime != 5 && ticket.screenTime != 8 && ticket.screenTime != 11);
system("pause");
}
感谢您的时间,我只是一个初学者,所以请耐心等待:(
答案 0 :(得分:0)
使用这样的幻数是相当不可维护的(添加新的允许时间不干净,你必须编辑条件等),你的版本与数组更好。本答案的其余部分侧重于使解决方案按照您希望的方式工作:
它非常有效(使用std::set
或std::unordered_set
可以提高效率,但对于如此少量的允许值,它可以忽略不计),这不是问题。您当前的版本与带阵列的版本一样快,因为您仍然比较相同数量的数字。
如果您的问题是它打印错误4次,那么保留一个布尔标志以指示用户输入了有效值,并在循环后检查:
const unsigned int VALID_TIMES_SIZE = 4;
bool validTime = false;
for (unsigned int i = 0; i < VALID_TIMES_SIZE; ++i)
{
if (ticket.screenTime == validTimes[i])
{
validTime = true;
break;
}
}
if (!validTime)
{
printf("Invalid Screen Time! Enter again please!\n");
// Redo the loop using continue, for example
}
答案 1 :(得分:0)
检查scanf的返回以确保它成功。如果不是,则需要清除输入流中的待处理字符。
#include <stdio.h>
typedef struct{
char movieName[20];
int screenTime;
float price;
int seatNum;
} MovieTicket;
int main( void) {
MovieTicket ticket;
int result = 0;
int validTime[] = {2, 5, 8, 11};
int limit = sizeof ( validTime) / sizeof ( validTime[0]);
int match = 0;
do{
match = 0;
printf("Enter your screen time: ");
if ( 1 == ( result = scanf("%d", &ticket.screenTime))) {
//check for matching validTime
for ( int each = 0; each < limit; each++) {
if ( validTime[each] == ticket.screenTime) {
match = 1;
break;
}
}
if ( !match) {
printf("Invalid Screen Time! Enter again please!\n");
result = 0;
}
}
else {
//scanf could not parse an int
printf("Enter Screen Time! Enter again please!\n");
while ( '\n' != getchar ( )) { }//clear input stream
}
} while ( result != 1);
system("pause");
}
答案 2 :(得分:-1)
为了使某些内容易于理解,您可以避免使用这些神奇的数字或将它们包装在像checkTime
这样的有意义的结构中,然后将其用于此类检查。这种方式假设下次你被要求在不同时间建立一个检查时间时,你不必寻找硬编码时间并用新东西替换它。
例如,你可以做这样的事情,
struct checkTime{
int *checkedTimes;
int length;
int (*checkIfTimeExists)(const struct checkTime* ch, int tm);
};
int checkTimerExistAux(const struct checkTime* ch,int tm)
{
for(int i=0;i<ch->length;i++)
if(ch->checktedTimes[i]==tm) return 1;
return 0;
}
Then you create an `initilaize` function which will allocate memory and do this hardcoded thing. (like putting times and all that)[2,5,8,11] in your case.
initialize(); // here you created the structure `checkTimeInst`
// struct checkTime* checkTimeInstPtr = malloc(sizeof(struct checkTime));
// checkTimeInstPtr->checkedTimes = malloc(sizeof(int)*N);
// checkTimeInstPtr->length = 0;
// checkTimeInstPtr->checkIfTimeExists = checkTimerExistAux;
do{
printf("Enter your screen time: ");
scanf("%d", &ticket.screenTime);
if(checkTimeInstPtr->checkIfTimeExists(checkTimeInstPtr,ticket.screenTime)==0){
printf("Invalid Screen Time! Enter again please!\n");
}
} while(checkTimeInstPtr->checkIfTimeExists(checkTimeInstPtr,ticket.screenTime)==0);
这不是关于加速,而是关于可维护性。
这里没有关于加速的事情。但是,如果您正在努力缩短时间,请尝试使用getchar()
或类似的方式自行使用阅读器或扫描仪。
最初发布的代码假定为C ++,其中OP要求C语言特定的答案或修改。在 Paul Griffiths 评论之后,我已将其修改为遵循该标准。