为什么这个例程 return 是一个长度为 0 的数组?

why does this routine return an array of length 0?

各位,这是我写的一个函数,用于读取用户输入,该输入是一个未知大小的双精度向量,当按下 'enter' 时输入必须终止:

vector<double> read_array()
{
    vector<double> array_in;

    double el;

    while (!cin.get())
    {
        cin >> el;
        array_in.push_back(el);
    }

    return array_in;
}

为了说明它,请考虑以下代码:

void init() // the function that calls the read_array function
{
    cout << "Enter array X: " << endl;
    
    vector<double> X = read_array();
    
    int l = X.size();

    cout << l << endl;
}

提示时的典型输入是: 1(space)2(space)3(space)4(输入)

当按下回车键时,输入终止,变量'l'被初始化但等于0 但是,当按下 enter 键时,数组大小为 0。调试它使它看起来永远不会像那样进入循环。

如果输入值不是数组,同样的例程效果很好。

在此先感谢大家!

我不知道您希望 std::cin.get() 做什么,但根据您的评论,您似乎希望它以某种方式处理行尾:它没有。它只是简单地读取下一个不太可能对你有好处的字符。特别是,如果字符不是 '[=13=]',取反将导致布尔值 false。也就是说,原则上循环应该工作 除非 您只输入一个数字值,后跟(可能在 space 之后)一个非数字或输入的结尾。

处理基于行的输入的最简单方法是使用 std::getline() 将行读入 std::string,然后使用 std::istringstream:[=26= 解析行]

std::vector<double> read_array() {
    std::vector<double> result;
    if (std::string line; std::getline(std::cin, line)) {
        std::istringstream lin(line);
        for (double tmp; std::cin >> tmp; ) {
            result.push_back(tmp);
        }
    }
    return result;
}

由于std::cin只涉及读行,解析double失败时不会设置std::cin.fail()。也就是说,你可以用doubles的数组读取多行,每行也可以为空。

如果您不想阅读辅助行,则需要更多地了解 C++ 中格式化输入的工作原理:它从跳过白色开始space。由于换行符是白色的space,你需要自己阅读白色的space,如果它恰好是换行符或非白色的space就停止。如果到达换行符(仍被提取),我将使用一个函数来跳过 returns false

bool skip_non_nl_ws(std::istream& in) {
    for (int c; std::isspace(c = in.peek()); std::cin.ignore()) {
        if (c == '\n') {
            return false;
        }
    }
    return true;
}

std::vector<double> read_array() {
    std::vector<double> result;
    for (double tmp; skip_non_nl_ws(std::cin) && std::cin >> result); ) {
        result.push_back(tmp);
    }
    return result;
}

此方法与 属性 相似,不会设置 std::ios_base::failbit。但是,如果一行中的任何字符无法解析为 double,则该位将被设置。这样你就可以检测输入错误。使用 std::getline() 的方法将继续到下一行。