c++ - 如何从用户输入中替换代码内部变量的值?

标签 c++

我正在尝试在我的程序中添加开发人员模式。由于汽车的关税每个月都会推迟,我想允许我的用户更改我程序中的每个变量,例如关税 lccost yen2taka 运费

#include <iostream>

using namespace std;

class A
{
public:
    int carbid,duty;

    void Input()
    {
        cout<<"please insert the car price you want to bid for(in yen): ";
        cin>>carbid;

        cout<<"duty of the car: ";
        cin>>duty;
    }

    int Exportcost()
    {
        int exportcost;
        int servicechrg=10;
        int freight=20;
        exportcost=servicechrg+freight+carbid;
        return exportcost;
    }

    int Yen2taka()
    {
        int yen2taka;
        int taka2dollarrate=10;
        int dollar2yen=1;

        yen2taka=((Exportcost())/dollar2yen)*taka2dollarrate;

        return yen2taka;
    }

    int Importcost()
    {
        int importcost;
        int lccost=10;
        int cnfcost=20;

        importcost=lccost+cnfcost;

        return importcost;
    }

    int Totalcosting()
    {
        int total;
        int myprofit=10; //80000

        total=myprofit+Importcost()+Yen2taka();

        cout<<total;

        return total;

    }

    void summary()
    {
        cout<<

    }


};

int main()
{
    x:
    A ob;
    ob.Input();
    ob.Exportcost();
    ob.Yen2taka();
    ob.Importcost();
    ob.Totalcosting();

    int ch;
    cout<<"press 1 to see the summery of the costing or 2 to restart costing again"<<endl;
    cin>>ch;
    switch(ch)
    {
       case 1:
          ob.summary();
          break;
       case 2:
          goto x;
    }
}

最佳答案

首先,您应该将这些参数收集在一个单独的类中:

class Configuration // maybe you find a better name...
{
    int m_servicechrg = 10; // default
    int m_freight = 20;
    // ...
public:
    int servicechrg() { return m_servicechrg; }
    void servicechrg(int value); { /* check some limits? */ m_servicechrg = value; }
    int freight() { return m_freight; }
    void freight(int value); { /* check some limits? */ m_freight = value; }
    // ...
};

// will allow you to do:
// C c; std::cout << c;
ostream& operator<<(ostream& s, Configuration const& c)
{
    // which ever formatting is appropriate...
    s << c.servicechrg() << ' ' << c.freight();

    return s;
}

setter 也可以返回 bool 来指示无效值。

现在你可以在 main 中使用这个类了:

Configuration c;
A a;

int cost = a.exportCost(c); // you'd have to adjust signatures...

int value;
switch(ch)
{
case 4:
    if(stc::cin >> freight) // catches invalid user input!
                            // one ALWAYS should do, otherwise you might end up in
                            // your program not working any more
    {
        c.freight(value);
        // or, if you have:
        if(!c.freight(value))
        {
            // some appropriate error message
            // (it's better not to output in the setter, you are more flexible this
            // way – maybe you want different messages at different occasions?)
        }
    }
    else
    {
        // appropriate error handling
    }
    break;
default:
    // handling invalid user input
    // again, you always should; but stream state is not in error state,
    // so you just can print appropriate error message
    break;
}

请参阅 this answer 以了解如何正确处理流错误。

如果您想了解错误处理的差异:第一种情况是用户输入非数字输入,例如 ss ,第二种情况是输入数字,但超出有效范围 ( 77)。

现在如果你不想一直将配置作为参数传递,你可以创建一个全局变量(但要小心,全局变量有一些危险,尽可能少用它们)或实现 singleton pattern .

旁注:goto 有时可以是一个很好的工具,但它是一个危险的工具(标签的名称 x 不是一个好名称,更喜欢一个能清楚表明意图的名称,例如REENTRY_POINTLOOP_START ,...)。如果您可以在不付出不合理努力的情况下相处,则更喜欢这样的变体:

bool isRunning = true;
do
{
    // ...
    case 2:
        isRunning = false;
        break;
}
while(isRunning);

当然,一个额外的变量,一个额外的检查;不幸的是,您不能使用 break 退出(伪)无限循环 (for(;;))(但不要将此模式应用于嵌套循环,然后它会变得越来越不可读 – 并且效率低下:bool isExit = false; for(int i = 0; !isExit && i < n; ++i) { for(j = 0; j < n; ++j) { isExit = true; break; } } – 明白我的意思吗?)。一个变体可能是:

for(;;)
{
    switch(ch)
    case 1:
        // ...
        //break; <- replace
        continue;
    case 2:
        //
        break;
    } // end of switch
    break; // break the surrounding for(;;) loop
}

但这也不是很好。

一个非常好的变体允许在给定的情况下退出循环,因为之后没有任何事情要做:

for(;;)
{
    switch(ch)
    {
    case 2:
        // maybe yet some cleaning up here
        return 0;
    default:
        // ...
        break;
    }
}

缺点:函数的退出点可能嵌套在代码中。

还有其他一些技巧可以实现这种模式,比如将代码的子部分打包到一个内部有返回值的 lambda 表达式中,然后直接调用它。但是现在真的开始超出范围了......

最后,如果您坚持使用 goto ,我的变体宁愿是:

for(;;)
{
    switch(ch)
    {
    case 2:
        // ...
        goto LOOP_EXIT;
    default:
        // ...
        break;
    }
}
LOOP_EXIT:
return 0; // e. g. main
(void)0;  // if there isn't anything to do in the function any more
          // (labels require an instruction afterwards!)

现在不会有隐藏循环,而且您实际在做什么更加明显。目前,这不是真正的问题,但如果您的代码增长,隐藏的循环会变得越来越难以发现。

在这种情况下,我会清楚地标记 goto 以便其他编码人员可以立即发现关键代码点:

///////////////////////////////////////////////////
// possibly some comment why applying this pattern
goto SOME_LABEL;
///////////////////////////////////////////////////

可以对深度嵌套的函数退出点 (return) 执行相同的操作。

关于c++ - 如何从用户输入中替换代码内部变量的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55980121/

相关文章:

c++ - 为 C++ STL 容器重载 << 运算符

C++ 返回 std::pair<int *,int *>?

c++ - opengl中灯光的区别

c# - 使用 MVVM 在运行时绑定(bind)失败

c++ - 将字符串流解析为字符串和 double

c++ - C++11 中具有 C 链接的复杂类型

c++ - 以随机顺序遍历数组

c++ - 检查初始化列表中的参数是否正确?

c++ - HLS - 使用循环时数组参数接口(interface)不同

c++ - 免费的跨平台 2D 图形游戏引擎