我正在尝试练习使用函数在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;
}
//================================================
谢谢。
答案 0 :(得分:1)
您的循环逻辑很好,但是正如Ruks指出的那样,变量 repeat 被遮盖了。
Output :
fileName : ABC1X_x0020_0400_x0020_0109-_x0028_1-2_x0029__v2.pdf
Decoded FileName :ABC1X 0400 0109-(1-2)_v2.pdf
修复很简单
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.
在包含的范围内重用名称是错误的常见来源。现在您知道应该避免什么了。
答案 1 :(得分:0)
我弄清楚了问题所在。实际上有两个问题。
我摆脱了上面其他用户提到的阴影重复变量。在主要功能中,我将循环类型切换为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保留在缓冲区中以备后用)。稍后在程序中,当询问用户是否要继续另一个循环时,编译器会自动在缓冲区中输入下一个字母(在我们的示例中为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,它将继续,如果遇到其他任何事件,它将停止。由于在我们的“是”示例中保存了E,并且由于E不是Y,所以程序确定该结束了。