【问题标题】:c++ input line to vectorc++ 输入行到向量
【发布时间】:2017-06-11 10:36:49
【问题描述】:

我的目标是在输入后立即将输入行添加到向量(输入命中)。 示例:

"1 2 3 4 5 6" - 行输入

成为持有该数字的向量

代码尝试:

int arrLength = validateArrLength("Enter array length: ");
vector<int> arr;
int counter = 1;

cout << "Enter values:" << endl;
string in;
cin.ignore();
getline(cin, in, ' ');

while (cin >> in && counter < arrLength){
    arr.push_back(atoi(in.c_str()));
    ++counter;
}

问题是在while循环中第一个值被忽略并跳转到第二个。我该如何处理?

【问题讨论】:

    标签: c++ vector input


    【解决方案1】:

    你应该有这样更简单的代码:

    int arrLength = validateArrLength("Enter array length: ");
    vector<int> arr;
    
    for(int val, i = 0;(cin >> val) && i < arrLength; ++i){
        arr.push_back(val);
    }
    

    【讨论】:

    • 当我输入让说'34 45 51'时它并没有在输入时停止
    • 可能从 1 开始循环
    • @TeodorKolev 为什么要问第一名的条目数?
    • @TeodorKolev 如果您想使用任意数量的条目,您可以要求用户提供一个空行(只需按 ENTER,无需进一步输入)以停止输入序列。
    • 我想输入 5 个数字并按 Enter 继续。该代码没有这样做
    【解决方案2】:

    我建议您避免使用原始循环,而是使用标准库来执行此操作。为了完成它,其中有几个结构:

    #include <algorithm>
    #include <iterator>
    #include <vector>
    #include <iostream>
    
    int main() {
      std::vector<int> arr;
      std::copy(std::istream_iterator<int>(std::cin),
                std::istream_iterator<int>(),
                back_inserter(arr));
    
      for(int i : arr)
        std::cout << i << ' ';
    }
    

    Live Example

    std::istream_iterator 旨在以您需要的确切形式处理输入(以空格分隔的行)。它还将更稳健地检测流的结尾。

    istream_iterator 创建的虚拟“输入范围”随后被馈送到std::copy 算法。这很明显,并将范围内的每个元素分配给 std::back_inserter 返回的迭代器。这个赋值本质上只是一个调用arr.push_back的包装器。


    如果你真的只想复制到一个点,标准库没有copy_until 算法。但是推出我们自己的并不难:

    #include <iterator>
    #include <vector>
    #include <iostream>
    
    template<typename InputIt, typename ForwardIt, typename UnaryPred>
    void copy_until(InputIt start, InputIt end, ForwardIt d_first, UnaryPred p) {
        while(start != end && p(*start))
          *d_first++ = *start++;
    }
    
    int main() {
      std::vector<int> arr;
      int count = 0;
      copy_until(std::istream_iterator<int>(std::cin),
                 std::istream_iterator<int>(),
                 back_inserter(arr), [&](int) {
                   return ++count < 3;
                 });
    
      for(int i : arr)
        std::cout << i << ' ';
    }
    

    Live Example

    【讨论】:

    • 它没有在输入命中时停止
    • 没有办法组合几个 STL 结构来组成copy_until()?我不确定,但不知何故重写 std::copy() 对我来说感觉不对。
    • @iksemyonov - 你可以通过从copy_if 的谓词内部抛出来破解它。那……我觉得更不对劲。
    • 这样,我明白了。在 Qt 上长大,我根本不想扔。但是为什么std::copy_if() 不用抛出/中止就不用谓词呢?一定是一个简单的问题,但不知何故我没有完全理解。
    • @iksemyonov - std::copy_if 总是遍历整个范围。谓词仅用于选择要复制的内容,而不是是否继续迭代。这可以在这里工作,但它不会像 OP 想要的那样抢先退出。
    猜你喜欢
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多