【问题标题】:Elegant solution to take input to a vector<int>将输入输入到 vector<int> 的优雅解决方案
【发布时间】:2017-12-03 22:40:09
【问题描述】:

我正在尝试创建一个大小未预定义的vector &lt;int&gt;。只要输入终端中有数字,它就应该输入数字,并且当我点击Enter 时应该停止阅读。我尝试了许多解决方案,包括给定的herehere。在第二种情况下,我可以输入一个非整数来终止向量的输入。如果我使用第一个解决方案(下面添加的代码),它会无限期地监听输入。

代码:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;

int main()
{
    //cout << "Enter the elements of the array: \n";
    //vector <int> arr ( std::istream_iterator<int>( std::cin ), std::istream_iterator<int>() );
    vector <int> arr;
    string buf;
    cout << "Enter the elements of the array: \n";
    while(getline(cin, buf))
    {
        istringstream ssin(buf);
        int input;
        while(ssin >> input)
        {
            arr.push_back(input);
        }
    }

    cout << "The array: \n";
    for(size_t i = 0; i < arr.size(); i++)
    {
        cout << arr[i] << " ";
    }
    return 0;
}

1) 我不觉得输入一个字符或一个很大的数字来结束收听输入是很优雅的。但是,istringstream 的解决方案似乎是要走的路。我不确定为什么它不起作用。

2) 有没有办法从键盘检测Enter 以终止监听输入?我尝试使用cin.get(),但它改变了向量中的数字。

3) 还有其他方法或建议吗?

【问题讨论】:

  • "有什么方法可以检测到键盘的 Enter"。 getline() 默认情况下采用 Enter 即 '\n' 作为分隔符。所以它读取一行输入并在输入时退出。你做了同样的事情,但在 while()
  • 但我在while() 中有getline()。我不确定我是否理解您的意思。
  • getline 放入while 意味着您希望继续获取所有行,直到输入关闭。但在你的问题中,听起来你想在得到一条线后停下来。
  • 如果你追求优雅,那你就选错了语言。

标签: c++ vector cin getline istringstream


【解决方案1】:

让我们一步一步来。

我们要向上阅读,直到按下 enter。这意味着您可能想使用std:getline 来读取一行。

然后你想解析它,所以你想把这行放到一个istringstream中。

然后你想读数字。当您阅读它们时,您显然想忽略除数字以外的任何内容,并且即使您看到一组无法转换为数字的数字,您也想继续阅读。

这留下了一些不完全清楚的东西,例如如何处理太大而无法转换的输入?你想直接跳到下一个吗?你想把一些数字读成一个数字,然后把剩下的数字读成另一个数字吗?

同样,如果你得到像“123a456”这样的东西,你想做什么?是否应该完全跳过它,读作“123”(而忽略“a456”)?是否应该读作“123”和“456”,而只忽略“a”?

暂时让我们假设我们要读取以空格分隔的字符组,并将所有这些字符转换为我们可以的数字。如果某些东西太大而无法转换为数字,我们将忽略它(全部)。如果我们有一个像“123a456”这样的组,我们会将“123”读取为数字,而忽略“a456”。

为此,我们可以这样做:

std::string line;
std::getline(infile, line);

std::istringstream input(line);

std::string word;
std::vector<int> output;

while (input >> word) {
    try {
        int i = std::stoi(word);
        output.push_back(i);
    }
    catch (...) {}
}

例如,给定输入如:“123a456 321 1111233423432434342343223344 9”,这将读入 [123, 321, 9]。

当然,我只是对您的要求进行猜测,我并没有努力使这个变得特别干净或优雅——只是对一组可能的要求的简单实现。

【讨论】:

  • 我从 cmets 得到了我想要的东西。但是 +1 用于使用 try catch 块来捕获边缘情况。
  • @skr_robo:您的回答甚至没有达到您在问题中要求的程度。例如,给定此处显示的输入,它将只读123,并因为“a”而停止,正如您在问题中指出的那样。
  • 我通过输入1 2 3 4 然后输入Enter 对其进行了测试。它停止收听输入。早些时候,我必须输入类似1 2 3 4 a 的内容才能获得相同的结果。如果我的问题中的措辞引起任何混淆,我很抱歉。
  • 我已重新阅读您的回答。我理解你的观点“例如,给定输入:“123a456 321 1111233423432434342343223344 9”,这将在 [123, 321, 9] 中读取。”但我的目标不是那个。很抱歉造成混乱。
【解决方案2】:

请查看来自@LearningC 和@M.M. 的cmets。

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;

int main()
{
    vector <int> arr;
    string buf;
    int input;
    cout << "Enter the elements of the array: \n";
    getline(cin, buf);
    istringstream ssin(buf);
    while(ssin >> input)
    {
        arr.push_back(input);
    }

    cout << "The array: \n";
    for(size_t i = 0; i < arr.size(); i++)
    {
        cout << arr[i] << " ";
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2018-04-28
    • 1970-01-01
    • 2011-03-31
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多