不断重复一个功能,直到用户说停止?

时间:2018-11-09 04:33:59

标签: c++ function loops

我正在尝试练习使用函数在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;
}
//================================================

谢谢。

2 个答案:

答案 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,所以程序确定该结束了。