C++ 移动黑白函数的初学者问题

C++ Beginner Issue with moving b/w Functions

本文关键字:初学者 问题 函数 移动 黑白 C++      更新时间:2023-10-16

这是我的第一篇 stackoverflow 帖子,所以如果写得不好之类的,请道歉,但我是 C++ 的超级初学者(在代码中可能很明显)并且正在尝试完成 100 编程挑战,我最多只能达到 #3 - 温度转换器。

的朋友有一些其他语言的编程经验,今晚将在我的github上浏览它,看看他是否无法弄清楚,但我想我也会尝试stackoverflow。

我不知道具体是什么导致了错误,所以我将不得不发布整个代码,但基本上我的问题是它编译得很好,但是当输入任何输入时,它会触发 cin.fail() 并且只是在函数之间循环和跳转几乎是自愿的,但从未输入 CelstoFahr() 或 FahrtoCels()。

如果我的代码很混乱,再次道歉,如果您有任何建议,请告诉我,并随时批评我的风格,因为我一直在寻求改进。如有必要,我还可以链接我的 github。

代码如下:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <limits>
// Forward declaring the functions
double CinFailCheck(double cin_fail_check);
double CelstoFahr(double celsius_amount, double fahrenheit_amount);
double FahrtoCels(double celsius_amount, double fahrenheit_amount);
int UserSelectionValidate(int user_selection);
void pauseAtEnd();
bool UserRestart();
void menu();
// Initializing the functions, with user input validation, for Cels -> Fahr, Fahr -> Cels and User Selection
double CinFailCheck(double cin_fail_check)
{
    while (std::cin.fail())
    {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        std::cout << "nBad entry, no text allowed! Enter a Number: ";
        std::cin >> cin_fail_check;
    }
    return cin_fail_check;
}
double CelstoFahr(double celsius_amount, double fahrenheit_amount)
{
    // Declaring cin_fail_check to enable me to have the cin.fail() as a function
    double cin_fail_check = 0;
    // Perform cin.fail() on the users input then grab that input and clone it to celsius_amount
    CinFailCheck(cin_fail_check);
    celsius_amount = cin_fail_check;
    std::cin.clear();
    std::cin.ignore();
    // Make conversion using the formula for C to F
    fahrenheit_amount = (celsius_amount * 1.8) + 32;
    return fahrenheit_amount;
}
double FahrtoCels(double celsius_amount, double fahrenheit_amount)
{
// Declaring cin_fail_check to enable me to have the cin.fail() as a function
double cin_fail_check = 0;
// Perform cin.fail() on the users input then grab that input and clone it to fahrenheit_amount
CinFailCheck(cin_fail_check);
fahrenheit_amount = cin_fail_check;
std::cin.clear();
std::cin.ignore();
// Make conversion using the formula for F to C
celsius_amount = (fahrenheit_amount - 32) * (5 / 9);
return celsius_amount;
}
int UserSelectionValidate(int user_selection)
{
    // Declaring cin_fail_check to enable me to have the cin.fail() as a function
    double cin_fail_check = 0;
    // Perform cin.fail() on the users input then grab that input and clone it to user_selection
    CinFailCheck(cin_fail_check);
    user_selection = cin_fail_check;
    std::cin.clear();
    std::cin.ignore();
    return user_selection;
}
// Function to enable a pause at the end to avoid the use of system("pause")
void pauseAtEnd() 
{
    std::cout << "nnPlease press Enter to exit . . .";
    std::cin.sync();
    std::cin.get();
}
// Restart function to avoid having to re-write it all each time
bool UserRestart()
{
    bool CONVERTER_RUNNING = true;
    bool BOOL_RETURNTOMENU = true;
    std::string user_returntomenu;
    // Check if the player wishes to make another conversion or exit the program
    while (BOOL_RETURNTOMENU == true)
    {
        std::cout << "nDo you wish to make another conversion? Y/N: ";
        std::cin >> user_returntomenu;
        std::cin.ignore();
        if (user_returntomenu == "Y" || user_returntomenu == "y" || user_returntomenu == "N" || user_returntomenu == "n")
        {
            if (user_returntomenu == "Y" || user_returntomenu == "y")
            {
                std::cin.clear();
                std::cin.ignore();
                menu();
            }
            else
            {
                std::cout << "nGoodbye";
                BOOL_RETURNTOMENU = false;
            }
        }
        else
        {
            std::cout << "nBad Entry! Numbers not allowed! Please enter Y or Nn";
            std::cin.clear();
            std::cin.ignore();
        }
    }
    CONVERTER_RUNNING = false;
    return CONVERTER_RUNNING;
}
// Writing the menu() function to enable loopback from the restart function
void menu()
{
    int user_selection = 0;
    double celsius_amount = 0;
    double fahrenheit_amount = 0;
    std::cout << "Welcome to the Temperature Converter!nn";
    std::cout << "1. Convert Celsius to Fahrenheitn";
    std::cout << "2. Convert Fahrenheit to Celsiusn";
    std::cout << "3. Exit programn";
    UserSelectionValidate(user_selection);
    if (user_selection == 1)
    {
        // Run Celsius to Fahrenheit function and retrieve the values to cout here
        CelstoFahr(celsius_amount, fahrenheit_amount);
        // cout the amounts received from the function
        std::cout << "n" << celsius_amount << " degrees Celsius is equal to " << fahrenheit_amount << " degrees Fahrenheit";
    }
    else if (user_selection == 2)
    {
        // Run Fahrenheit to Celsius function and retrieve the values to cout here
        FahrtoCels(celsius_amount, fahrenheit_amount);
        // cout the amounts received from the function
        std::cout << "n" << fahrenheit_amount << " degrees Fahrenheit is equal to " << celsius_amount << " degrees Celsius";
    }
    else if (user_selection == 3)
    {
        std::cout << "nGoodbye";
    }
    else
    {
        std::cin.clear();
         std::cin.ignore();
        std::cout << "nPlease enter a number between 1 and 3 for your selection!nn";
        UserSelectionValidate(user_selection);
    }
}
int main()
{
    // Declare boolean variable to keep converter running
    bool CONVERTER_RUNNING = true;
    while (CONVERTER_RUNNING == true)
    {
        menu();
        UserRestart();
    }
    pauseAtEnd();
    return 0;
}

这里有一个问题:

UserSelectionValidate(user_selection);

这不会对user_selection产生影响,因为它是按值传递的,并且不使用返回值。 也许你的意思是

user_selection = UserSelectionValidate();

只需在UserSelectionValidate本地声明user_selection:

int UserSelectionValidate()
{
    // Declaring cin_fail_check to enable me to have the cin.fail() as a function
    double cin_fail_check = 0;
    // Perform cin.fail() on the users input then grab that input and clone it to user_selection
    CinFailCheck(cin_fail_check);
    int user_selection = cin_fail_check;
    std::cin.clear();
    std::cin.ignore();
    return user_selection;
}

CinFailCheck()也有类似的问题。

您需要编写正确的代码来存储输入user_selection

std::cout << "Welcome to the Temperature Converter!nn";
std::cout << "1. Convert Celsius to Fahrenheitn";
std::cout << "2. Convert Fahrenheit to Celsiusn";
std::cout << "3. Exit programn";
UserSelectionValidate(user_selection);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

将上述行替换为:

std::cin >> user_selection;

然后,请确保要求转换输入值。你可以这样做。

您需要了解按值传递,并按引用传递。在几乎所有函数中,您都是按值传递的,而不是使用返回值。按值传递时,通过复制传递给它的局部变量来创建局部变量(在堆栈上)。修改它时,您不会修改传递的原始变量。

例如,在下面的代码中,cin_fail_check永远不会改变,它将始终具有初始化值 0,因为 CinFailCheck 不会修改它;您可以看到如何从中获得无限循环。

// Declaring cin_fail_check to enable me to have the cin.fail() as a function
double cin_fail_check = 0;
// Perform cin.fail() on the users input then grab that input and clone it to user_selection
CinFailCheck(cin_fail_check);
int user_selection = cin_fail_check;

更改函数定义以进行引用。例如:double CinFailCheck(double& cin_fail_check)或使用返回值。

"何时按值、引用和指针传递参数"http://www.cplusplus.com/articles/z6vU7k9E/