使用带有cin的getline来指定用户输入

时间:2013-10-29 03:12:20

标签: c++

每次在此函数中输入类型出错时,它会自动将* _cost的值设置为0.为什么会发生这种情况?

void Item::setCost(string input){
float entered;
istringstream stin;
stin.str(input);
if(!(stin >> entered)){
    do{
        cout << "invalid input" << endl;
        stin.clear();
        getline(cin, input);
        stin.str(input);
        *_cost = entered;
    }
    while(!(stin >> entered));
}
else{
    *_cost = entered;
}
}

我在main函数中使用函数如下:

istringstream stin;
string input;

cout << "enter cost" << endl;
getline(cin, input);
items[i]->setCost(input);

3 个答案:

答案 0 :(得分:1)

您正在将*_cost设置为一个值,因为if语句始终是一个必然不正确的值。
*_cost = entered行仅在程序通过其“无效输入”代码时执行。程序仅在输入时打印“无效输入”不是合法值。因此,_cost只能设置为非法值 要解决您的问题,请在执行循环后放置*_cost = entered

我不确定你为什么不直接使用std :: cin来读取数据,而不是将标准输入转换为std :: string的实例然后转换为istringstream。

答案 1 :(得分:1)

您需要将*_cost = entered块中的第一个do .. while移出,以成为其后的第一个语句。完成后,您会看到另一个重构有用,虽然不是必需的。

while(!(stin >> entered))
{
    cout << "invalid input" << endl;
    stin.clear();
    getline(cin, input);
    stin.str(input);
}
*_cost = entered;

答案 2 :(得分:0)

在代码中执行*_cost = entered;时,entered无效。

我刚刚用你的初衷纠正了你的代码

bool Item::setCost(string input) {
    bool ret_val = true;
    float entered = 0.0;
    istringstream stin;
    stin.str(input);

    while ( !(stin >> entered) ) {  // loop till you read a valid input 
        if ( !stin.rdbuf()->in_avail() ) {
            ret_val = false;
            break;
        }
    }

    *_cost = entered;
    return ret_val;
}

stin.rdbuf()->in_avail()可用于获取准备从字符串流中读取的可用字符数,您可以使用它来检查字符串流是否为“空”。

例如,如果你想从istringstream中提取一个浮点数,但你得到其他东西(失败条件),然后看看是否有任何遗留的字符(即数字)你可以检查stin.rdbuf()->in_avail() == 0。< / p>