简体   繁体   English

如何从用户(这是一个列表)获取输入并将值存储在 C++ 中的数组中?

[英]How to take input from user ( which is a list ) and store values in array in c++?

Testcase 1: {1, 2, 3, 4, 5}测试用例 1:{1、2、3、4、5}

Testcase 2: {5, 8, 9}测试用例 2:{5, 8, 9}

Is there any better solution than this for storing the values in an array in c++??有没有比这更好的解决方案来将值存储在 C++ 中的数组中?

Note: we dont know the size of the array to be created at compile time.注意:我们不知道编译时要创建的数组的大小。

#include<iostream>
#include<sstream>
#include<vector>
using namespace std;

int main(){
  string s;
  cin.ignore();
  getline(cin,s);
  string t;
  stringstream x(s);
  vector<int>v;
  while(getline(x,t,' ')){
      if(t[0]!='{' && t[0]!='}'&& t[0]!=','){
           v.push_back(stoi(t));
        }
   }
 int size=v.size();
 int arr[size];
 for(int i=0;i<size;i++) arr[i]=v[i];
// for(int i=0;i<size;i++) cout<<arr[i]<<" ";
}

Yes, it is possibile take an unknown number of integers.是的,可以采用未知数量的整数。 We can use a std::vector我们可以使用std::vector

We could write a function for doing that.我们可以为此编写一个函数。 Here we will split the string and return a std::vector .在这里,我们将拆分字符串并返回一个std::vector In C++ we can make use of RVO, Return Value Optimization.在 C++ 中,我们可以利用 RVO,返回值优化。 You may read here about copy elision and RVO.您可以在此处阅读有关复制省略和 RVO 的信息。 Basically it says, that you will not have a problem with copying bytes when returning containers from a function by value.基本上它说,当按值从函数返回容器时,复制字节不会有问题。 It is now even the recommended way to do so.现在它甚至是推荐的方法。

So, you can (and should) return a std::vector from a function.因此,您可以(并且应该)从函数返回一个std::vector The compiler will take care that this works in an optimized way.编译器会注意它以优化的方式工作。

But first, please see the below example:但首先,请看下面的例子:

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

std::vector<int> parseInts(std::string str) {

    // Put the string into a stream
    std::istringstream iss{ str };

    // Return the vector of ints 
    return { std::istream_iterator<int>(iss), {} };
}

int main() {
    // Test data
    std::string test{ "1 2 3 4 5 6 7 8 9 10" };

    // Get the vector with the ints
    std::vector ints = parseInts(test);

    // Show output
    for (const int i : ints) 
        std::cout << i << "\n";
    return 0;
}

We have a function called parseInts consisting of just 2 lines of code.我们有一个名为parseInts的函数, parseInts包含 2 行代码。

First, we we put the string into an std::istringstream .首先,我们将字符串放入std::istringstream With that, it would be possible to extract int from the new stream, like in这样,就可以从新流中提取 int,例如

std::istringstream iss{ str };
int i1, i2;
iss >> i1 >> i2;

The extractor operator >> will "extract" space delimited integer values from the stream (the string).提取运算符 >> 将从流(字符串)中“提取”以空格分隔的整数值。

But, if we look at it, we see, that then we need to know the number of integers in the string, and then repeatedly write ">>".但是,如果我们看一下,我们会看到,那么我们需要知道字符串中的整数个数,然后重复写“>>”。 For doing things repeatedly for the same number of items, like integers, we have iterators in C++.为了对相同数量的项目重复执行操作,比如整数,我们在 C++ 中有迭代器。 With iterators you can iterate over similar elements in a container.使用迭代器,您可以迭代容器中的相似元素。 If you assume a string to be a container, you can of course iterate over the integers in it.如果你假设一个字符串是一个容器,你当然可以迭代其中的整数。 There are iterators available that do this for us.有可用的迭代器可以为我们执行此操作。

In the case of a stream, we have the std::istream_iterator .在流的情况下,我们有std::istream_iterator This thing will iterate over all space delimited items of a certain type in the input stream and return the values.这个东西将迭代输入流中某种类型的所有空格分隔项并返回值。

The many values , that this iterator return, can best be stored in a std::vector , because it is a dynamically growing container.这个迭代器返回的许多值最好存储在std::vector ,因为它是一个动态增长的容器。 Ideal for us, becuase we do not know the number of integers in the stream in advance.非常适合我们,因为我们事先不知道流中的整数数量。

If we look at the std::vector , we find out that it has a so called range constructor.如果我们查看std::vector ,我们会发现它有一个所谓的范围构造函数。 Please see here: range constructor (number 5) .请参阅此处:范围构造函数(编号 5)

With the range constructor we define a variable of type std::vector and initialize it with a "begin" and an "end" iterator.使用范围构造函数,我们定义了一个std::vector类型的变量,并用“begin”和“end”迭代器初始化它。 Values in this range, will be put into the vector.此范围内的值将被放入向量中。

If we define the variable of type std::vector in our example, we could write:如果我们在示例中定义std::vector类型的变量,我们可以这样写:

std::vector<int> intv{ std::istream_iterator<int>(iss), std::istream_iterator<int>() };

or或者

std::vector<int> intv( (std::istream_iterator<int>(iss)), std::istream_iterator<int>() );

Please note the braces for the first argument.请注意第一个参数的大括号。 This is necessary to protect against the most vexing parse problem.这对于防止最棘手的解析问题是必要的。 You do not want to define a function, but a variable.你不想定义一个函数,而是一个变量。

But we will anyway not use it.但无论如何我们都不会使用它。 Because, with uniform initalization and the {}-initializer as the default-initializer, we can use the default for the 2nd parameter.因为,使用统一初始化和 {} 初始化器作为默认初始化器,我们可以使用默认值作为第二个参数。 Now we could write:现在我们可以写:

std::vector<int> intv(std::istream_iterator<int>(iss), {});

So, next, we can make usage of CTAD, Class template argument deduction .所以,接下来,我们可以使用 CTAD, 类模板参数推导 Basically, the compiler knows from the parameters in the constructor, what datatype of the container it will construct.基本上,编译器从构造函数中的参数知道它将构造的容器的数据类型。 So, no need to write it.所以,没必要写。

Now:现在:

std::vector intv(std::istream_iterator<int>(iss), {});

This looks already very nice and you could now return the variable intv.这看起来已经很不错了,您现在可以返回变量 intv。

But there is more.但还有更多。 The compiler knows the type of the function and what it should return.编译器知道函数的类型以及它应该返回什么。 So, you can use a braced initializer and return that and the compiler knows, that you want to return a std::vector<int>因此,您可以使用花括号初始化器并返回它,编译器知道您想要返回std::vector<int>

So the final statement is:所以最后的声明是:

return { std::istream_iterator<int>(iss), {} };

I hope it helps.我希望它有帮助。

And sorry for the long description for the one line of code.很抱歉对一行代码进行了冗长的描述。

So, now, for reading more lines you can write:所以,现在,为了阅读更多的行,你可以写:

int main() {

    // Her we will store the data
    std::vector<std::vector<int>> data{};

    // Read lines. Stop input with CRTL Z in an empty new line
    for (std::string line{}; std::getline(std::cin, line); ) {

        // Put the string into a stream
        std::istringstream iss{ line };

        // Split the values and add the values to the vector
        data.emplace_back(std::vector{ std::istream_iterator<int>(iss), {} });
    }

    // Show output
    for (const std::vector<int>& vi : data) {
        for (const int i : vi) std::cout << i << " ";
        std::cout << "\n";
    }
}

Stop input by typing CRTL Z in an empty line after the end.通过在结束后的空行中键入 CRTL Z 来停止输入。

Please try with inputting:请尝试输入:

1 2 3 4
5 6 7 8
CTRL Z

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何接受用户输入,对该输入进行数学运算,并将结果存储在数组中? 在 C++ - how to take user input, do math to that input, and store the results in an array? in C++ C++//如何存储来自用户输入的值? - C++//How to store values from user input? c++ - 如何将用户输入存储到数组中 - How to store user input to array in c++ 如何从控制台输入学生的全名(包括空格)并将其存储在c ++中的数组中? - How do I take full name of students(including space) as input from console and store it in an array in c++? 如何将用户字符串输入存储在数组中,C ++ - How to store user string input in array, C++ 如何从数组中获取输入并将其输入到C ++中的方程式中? - How to take inputs from array and input it into an equation in C++? 如何一次将来自用户输入的多个值存储到向量中(在 C++ 中)? - How do I store multiple values from user input into a vector at once (in c++)? 如何将不是来自用户输入的值存储在 c++ 中的变量中? - How to store a value not from user input in a variable in c++? 如何将同一行中的多个整数作为输入并将它们存储在 c++ 中的数组或向量中? - How to take multiple integers in the same line as an input and store them in an array or vector in c++? 我想接受用户输入并将其放入字符串数组c ++ - I want to take user input and put it into an array of strings c++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM