连续重复一个功能,直到用户说停止



我正在尝试使用函数在C++中练习编写代码,我基本上是对的,除了最后一部分,我试图提示用户询问他们是否愿意再次重复该函数。到目前为止,发生了两件事中的一件。该函数在不提示用户的情况下结束,或者该函数使用输入的参数连续循环。

我尝试过使用do while循环和简单while循环。但我似乎不明白我做错了什么?

#include <iostream>
#include <iomanip>
using namespace std;
void getTime24(int& hour, int& minute);
bool daylightSavingsTime(bool& DST);
int  convertTime24to12(int hour);
void printTime24(int hour, int minute);
void printTime12(int hour, int hour12, int minute);
void printJapanTime(int hour, int minute, bool DST);
bool userWantsToContinue(bool& repeat);
int main() {
int hour = 0;
int hour12 = 0;
int minute = 0;
bool DST = false;
bool repeat = true;
while (repeat == true) {
// Enter a time value
getTime24(hour, minute);
// Check for daylight savings time
daylightSavingsTime(DST);
cout << endl;
// Convert to 12 hour format
hour12 = convertTime24to12(hour);
// Print the time in 24 hour format
printTime24(hour, minute);
cout << " in Portland." << endl;
// Prints out the time and the AM/PM designation (e.g. 14:32 becomes 2:32 PM)
printTime12(hour, hour12, minute);
cout << " in Portland." << endl;
cout << endl;
// Prints out the current time in Tokyo
printJapanTime(hour, minute, DST);
cout << endl;
// Continue?
bool repeat = userWantsToContinue(repeat);
cout << endl;
if (repeat == false)
break;
}
return 0;
}

//FUNCTIONS
//================================================
// This function is to take in and store the 24 hour time.  It stores the times before 
// and after the colon as hours and minutes respectivly, and reads the colon as a char
// then passes all three parts as an input.  The colon is ignored.
void getTime24(int& hour, int& minute) {
char ch;
if (minute == '0') {
minute = printf("00");
}
else {
minute = minute;
}
cout << "Enter a time in a 24 hour format (e.g. 14:30): ";
cin >> hour >> ch >> minute;
while (hour > 24 || minute > 59) {
cout << "That is not a valid time.n";
cout << "Enter a time in a 24 hour format (e.g. 14:30): ";
cin >> hour >> ch >> minute;
}
}
//================================================
// This function checks for daylight savings time which will be used in the time zone
// conversion later.  It takes the first letter of a yes or no answer and turns that
// into a bool answer.
bool daylightSavingsTime(bool& DST) {
char yesNo;
cout << "Is it daylight savings time now? ";
cin >> yesNo;  // Takes only the first letter of the inputed answer to daylight savings
yesNo = tolower(yesNo);  // Converts letter to uppercase to allow for fewer compairsons
if (yesNo == 'y')
DST = true;
else 
DST = false;
return DST;
}
//================================================
// This block of code will convert the previously entered 24 hour time and convert it
// to a 12 hour time format.  It will do this by adding 12 to the hours and using the 
// result to determine if the time is AM or PM.  It will return the time to be stored.
int  convertTime24to12(int hour) {
int hour12 = 0;
int timeCheck = hour + 12;
if (timeCheck >= 25) {
hour12 = timeCheck - 24;
}
else {
hour12 = timeCheck - 12;
}
return hour12;
}
//================================================
// This block of code will print out the time in a 24 hour format.
void printTime24(int hour, int minute) {
cout << "The current time (24 hour format) is " << hour << ":" << minute;
}
//================================================
// This block of code will print out the 12 hour format of the time by checking the hour
// variable as a reference.  If it detects that it is in the afternoon (i.e. the hour is
// 12 or greater) then it will print out the time as a PM time, otherwise it will print out
// an AM time.
void printTime12(int hour, int hour12, int minute) {
if (hour > 11)
cout << "The current time (12 hour format) is " << hour12 << ":" << minute << " PM";
else
cout << "The current time (12 hour format) is " << hour12 << ":" << minute << " AM";
}
//================================================
// This block of code will take daylight savings time into account and convert the current
// time in Portland to the current time in Tokyo.  It will then print out the current time.
// Check time conversions at https://savvytime.com/converter/jst-to-pst/sep-3-2018/11-30am

void printJapanTime(int hour, int minute, bool DST) {
int japanHour = 0;
int japanHour12 = 0;
if (DST == true) {
if (hour > 8) {
japanHour = hour - 8; // from hour - 24 hours + 16 hours for the time conversion.
}
else {
japanHour = hour + 16;
}
printTime24(japanHour, minute);
cout << " in Tokyo." << endl;
japanHour12 = convertTime24to12(japanHour);
printTime12(japanHour, japanHour12, minute);
cout << " in Tokyo." << endl;
}
else if (DST == false) {
if (hour > 7) {
japanHour = hour - 7; // from hour - 24 hours + 17 hours for the time conversion.
}
else {
japanHour = hour + 17;
}
printTime24(japanHour, minute);
cout << " in Tokyo." << endl;
japanHour12 = convertTime24to12(japanHour);
printTime12(japanHour, japanHour12, minute);
cout << " in Tokyo." << endl;
}
}
//================================================
// This block of code will determine if the user wants to continue the program or not.
// This will be used in a do while loop, as soon as stop becomes true, we exit the loop.
bool userWantsToContinue(bool& repeat) {
char yesNo;
cout << "Would you like to convert another time? ";
cin >> yesNo;
yesNo = toupper(yesNo);  // Converts letter to uppercase to allow for fewer compairsons
if (yesNo == 'Y') {
repeat = true;
}
else
repeat = false;
return repeat;
}
//================================================

谢谢。

您的循环逻辑很好,但正如Ruks所指出的,变量repeat是隐藏的。

bool repeat = true;   // as written in your program, this variable never changes value
// let's call it repeat_1
while (repeat)        // here you test repeat_1
{
// ...
// Continue?
bool repeat = userWantsToContinue(repeat); // here you are declaring a second 
// variable named repeat, why?
// let's call it repeat_2
// it hides the var repeat declared outside the loop.
cout << endl;
if (repeat == false)                       // this tests repeat_2, and eventually exits the loop
break;                                 // I guess that's a fix you made to make 
// your program work.
}
assert(repeat == false);   // this assertion would invariably fail, since repeat_1
// is still true.
// note that repeat_2 is out of scope, it doesn't exist anymore.

修复是简单的

bool repeat = true;          
while (repeat)
{
//...
repeat = userWantsToContinue(repeat);  // note this is NOT a declaration,
// there is only one variable called repeat
}
assert(repeat == false);   // this assertion would invariably succeed, since
// repeat has to be false to exit the loop.

重复使用包含范围中的名称是常见的错误来源。现在你知道应该避免什么了。

我发现了问题所在。实际上有两个问题。

我去掉了上面其他用户提到的阴影重复变量。在主函数中,我将循环类型切换为do…while循环。我将bool变量初始化为true,这样循环就不会立即退出,所以它看起来像这样:

// FUNCTION
// Asks the user if they want to go again, 
// if they say yes the function repeats, if no then the program ends.
bool userWantsToContinue(bool repeat);
int main()
bool repeat = true;
do {
...
// Continue for another iteration of the loop?
repeat = userWantsToContinue(repeat);
cout << endl << endl;
}while(repeat != false);  // while repeat is true, keep doing the loop
...
//============================================================================================
// This block of code will determine if the user wants to continue the program or not.
// This will be used in a do while loop, in main() as soon as stop becomes true, we exit the loop.
bool userWantsToContinue(bool repeat) {
char yesNo;
bool repeat1 = 0;
cout << "Would you like to convert another time? ";
cin >> yesNo;
cin.ignore(100, 'n');
yesNo = toupper(yesNo);  // Converts letter to uppercase to allow for fewer compairsons
if (yesNo == 'Y') 
repeat1 = true;
else if (yesNo == 'N')
repeat1 = false;
return repeat1;
}
//============================================================================================

此外,每当用户输入一个简单的Y或N字母时,程序都会像它应该执行的那样执行,然而,如果他们要输入一个完整的单词(即是或否(,那么循环将在程序完成一次迭代后立即退出。我通过使用cin.ignore(NUMBER OF CHARACTERS TO BE IGNORED, 'CHARACTER THAT AUTOMATICALLY CLEARS OUT THE REST OF THE BUFFER IF ENCOUNTERED');命令清除缓冲区来解决这个问题。

如果缓冲区尚未清除,则会保存未使用的字母(例如,如果您输入yes,程序将使用Y,并将e和S保留在缓冲区中以备以后使用(。稍后,在程序中,当它询问用户是否愿意继续另一个循环时,编译器会自动在缓冲区中输入下一个字母(在我们的示例中,E来自YES(。通过在使用信件后立即清除缓冲区,这解决了问题。

例如,我有一个代码块,询问用户当前是否为夏令时。在我有这个代码块之前:

bool daylightSavingsTime(bool& DST) {
char yesNo;
cout << "Is it daylight savings time now? ";
cin >> yesNo;  // Takes only the first letter of the inputted answer to daylight savings
yesNo = tolower(yesNo);  // Converts letter to uppercase to allow for fewer compairsons
if (yesNo == 'y')
DST = true;
else 
DST = false;
return DST;
}

在添加了cin.ignore(100, 'n');之后,我清除了多余的未使用的字母。在这种情况下,我说,忽略后面的100个字符,或者在遇到新行(\n(时继续。

所以现在我的固定代码是这样的:

bool daylightSavingsTime(bool& DST) {
char yesNo;
cout << "Is it daylight savings time now? ";
cin >> yesNo;  // Reads only the first letter of the inputted word to daylight savings time
cin.ignore(100, 'n');  // clears all of the other characters that weren't used (e.g. 'es' in 'yes')
yesNo = toupper(yesNo);  // Converts letter to uppercase to allow for fewer compairsons
if (yesNo == 'Y')  // if the inputted word/letter begins with a Y do set the value of DST to true
DST = true;
else  // if the inputted word/letter does not begin with a Y then set the value of DST to false
DST = false;
return DST;
}

顺便说一句,else语句是在缓冲区未事先清除的情况下提前退出循环的原因。在YES示例中,E是缓冲区中的下一个字符。由于E没有立即使用,因此将其保存为以后使用。在代码的后面,当它询问用户是否愿意进行另一个循环时,会使用相同的逻辑。如果程序遇到Y,它将继续,如果遇到其他任何情况,它将停止。由于YES示例中的E被保存,并且E不是Y,程序决定是时候结束了。

相关内容

  • 没有找到相关文章

最新更新