-5
#include <bits/stdc++.h>
#include <vector>
using namespace std;
int main(){
    //first question
    vector<vector<string> > sample{ {"Hello"}, {"World"} };
    vector<vector<string> > test;
    test[0][0]=sample[0][0]; //doesnt work
    test[0][0].push_back(sample[0][0]); //still doesnt work
    test.insert(0,0,sample[0][0]); //also doesnt work
    //second question
    test[1][0].push_back("Hello"); //doesnt work
    //nothing works
    //how?????????
}

I am trying to write C++ program that copies an element from a specific location of a vector into another specific location of a vector. Example: I want to copy element sample[0][0] which is "Hello" into test[0][0]. I tried above methods and nothing worked. Second question would be if I want to copy sample[0][1] which is "World" into test[100][100], how?

Ps. A copy of the errors

[test.cc 2020-02-29 12:51:27.385]
,,test.cc: In function ‘int main()’:
test.cc:5:75: error: no matching function for call to ‘std::vector<std::vector<std::__cxx11::basic_string<char> > >::vector(<brace-enclosed initializer list>)’
    5 |     vector<vector<string> > sample{ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
      |                                                                           ^
In file included from /usr/include/c++/9/vector:67,
                 from /usr/include/c++/9/functional:62,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/c++/9/bits/stdc++.h:65,
                 from test.cc:1:
/usr/include/c++/9/bits/stl_vector.h:650:2: note: candidate: ‘template<class _InputIterator, class> std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&)’
  650 |  vector(_InputIterator __first, _InputIterator __last,
      |  ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:650:2: note:   template argument deduction/substitution failed:
test.cc:5:75: note:   couldn’t deduce template parameter ‘_InputIterator’
    5 |     vector<vector<string> > sample{ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
      |                                                                           ^
In file included from /usr/include/c++/9/vector:67,
                 from /usr/include/c++/9/functional:62,
                 from /usr/include/c++/9/pstl/glue_algorithm_defs.h:13,
                 from /usr/include/c++/9/algorithm:71,
                 from /usr/include/x86_64-linux-gnu/c++/9/bits/stdc++.h:65,
                 from test.cc:1:
/usr/include/c++/9/bits/stl_vector.h:622:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  622 |       vector(initializer_list<value_type> __l,
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:622:7: note:   candidate expects 2 arguments, 3 provided
/usr/include/c++/9/bits/stl_vector.h:604:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&, const allocator_type&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  604 |       vector(vector&& __rv, const allocator_type& __m)
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:604:7: note:   candidate expects 2 arguments, 3 provided
/usr/include/c++/9/bits/stl_vector.h:586:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&, const allocator_type&, std::false_type) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::false_type = std::integral_constant<bool, false>]’
  586 |       vector(vector&& __rv, const allocator_type& __m, false_type)
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:586:23: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘std::vector<std::vector<std::__cxx11::basic_string<char> > >&&’
  586 |       vector(vector&& __rv, const allocator_type& __m, false_type)
      |              ~~~~~~~~~^~~~
/usr/include/c++/9/bits/stl_vector.h:582:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&, const allocator_type&, std::true_type) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::true_type = std::integral_constant<bool, true>]’
  582 |       vector(vector&& __rv, const allocator_type& __m, true_type) noexcept
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:582:23: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘std::vector<std::vector<std::__cxx11::basic_string<char> > >&&’
  582 |       vector(vector&& __rv, const allocator_type& __m, true_type) noexcept
      |              ~~~~~~~~~^~~~
/usr/include/c++/9/bits/stl_vector.h:572:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&, const allocator_type&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  572 |       vector(const vector& __x, const allocator_type& __a)
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:572:7: note:   candidate expects 2 arguments, 3 provided
/usr/include/c++/9/bits/stl_vector.h:569:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  569 |       vector(vector&&) noexcept = default;
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:569:7: note:   candidate expects 1 argument, 3 provided
/usr/include/c++/9/bits/stl_vector.h:550:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  550 |       vector(const vector& __x)
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:550:7: note:   candidate expects 1 argument, 3 provided
/usr/include/c++/9/bits/stl_vector.h:519:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::vector<std::__cxx11::basic_string<char> >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  519 |       vector(size_type __n, const value_type& __value,
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:519:24: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘std::vector<std::vector<std::__cxx11::basic_string<char> > >::size_type’ {aka ‘long unsigned int’}
  519 |       vector(size_type __n, const value_type& __value,
      |              ~~~~~~~~~~^~~
/usr/include/c++/9/bits/stl_vector.h:507:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  507 |       vector(size_type __n, const allocator_type& __a = allocator_type())
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:507:7: note:   candidate expects 2 arguments, 3 provided
/usr/include/c++/9/bits/stl_vector.h:494:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector(const allocator_type&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  494 |       vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:494:7: note:   candidate expects 1 argument, 3 provided
/usr/include/c++/9/bits/stl_vector.h:484:7: note: candidate: ‘std::vector<_Tp, _Alloc>::vector() [with _Tp = std::vector<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::vector<std::__cxx11::basic_string<char> > >]’
  484 |       vector() = default;
      |       ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:484:7: note:   candidate expects 0 arguments, 3 provided

[test.cc 2020-02-29 12:54:15.771]
,,test.cc: In function ‘int main()’:
test.cc:5:5: error: ‘test’ was not declared in this scope
    5 |     test[1][0].push_back("Hello");
      |     ^~~~

This all the crap I see everytime I compile something that have vectors in it.

epixinvites
  • 57
  • 1
  • 8
  • 5
    The "crap" you see is not generated from the code you show us. It shows how you tried to initialize a 2D-vector of `std::string` with ints. Next, please read [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h), obviously you don't know what it does. – Lukas-T Feb 29 '20 at 13:05

3 Answers3

3

You need to resize the vector before attempting to access a specific index, which in your case means resizing the outer vector as well as all the inner vectors. For example, if you want to access test[100][100] you first need to do the following:

// since the index is zero-based you need a vector of
// 101 elements to access 100th element
test.resize(101); 
for (auto &inner : test)
    inner.resize(101);

// now you can do this
test[100][100] = sample[0][1];

Everything else you've tried didn't work because you were trying to call either a non-existent method or used a wrong object. For example, test[0][0] is a string which does have push_back but for characters which is probably not what you were trying to do, so instead you could've done this:

test.push_back({}); // add empty vector to the outer vector
test[0].push_back(sample[0][0]); // add your string to the first inner vector
r3mus n0x
  • 5,954
  • 1
  • 13
  • 34
2

Lets go through it step by step. But the most important thing is, to think about what you are coding. Your program will always do exactly what you programmed it to do, not neccesarily what you want it to do.

test[0][0]=sample[0][0];

This goes out of bounds, since test is empty, undefined behaviour ensues and most likely a segfault.

test[0][0].push_back(sample[0][0]);

Still out of bounds. In addition, think about what test[0][0] is. It's a std::string, so you are calling std::string::push_back, which can be used to append a single char to the end of the string, not to assign a value to it.

test.insert(0,0,sample[0][0]);

test is still just a std::vector, it does not "know" that it's used as a 2D-vector and the signature of insert does not magically change to reflect the usage of a vector.

test[1][0].push_back("Hello"); 

That's the same as the second one.

Now, how should it be done? You need to make sure test has a sufficient size, for example you can do

std::vector<std::vector<std::string>>> test(1); // initialize with 1 element
test[0].push_back(sample[0][0]); // append element from sample[0][0] to the first vector

But that's just one way. Only make sure your access doesn't go out of bounds.

Lukas-T
  • 11,133
  • 3
  • 20
  • 30
  • but what if I want to push_back an element at test[2592][72]? – epixinvites Feb 29 '20 at 13:45
  • You need to make sure `test` has an appropriate size. For example you could use the [`resize`](https://en.cppreference.com/w/cpp/container/vector/resize) function. – Lukas-T Feb 29 '20 at 14:13
1

The short answer to your question is that you need to 'size' the vector 'test' first; you are trying to access vector elements that do not exist (not just the value doesn't exist, but the vector element itself).

E.g.:

This:

    vector<vector<string> > sample{ {"Hello"}, {"World"} };

creates a vector of vectors of strings; it has size 2. sample[0] is a vector of strings of size 1. sample[0][0] is "Hello".

This:

    vector<vector<string> > test;

creates an empty vector of vectors of strings. It has no size. test[0] doesn't exist yet, calling it will likely result in a segfault.

Example using one-D vectors:

    std::vector<std::string> sample = {"a", "b", "c"};
    std::vector<std::string> test;
    test.push_back(sample[0]);
    std::cout<<test[0]<<"\n";

For two-d vectors, you have to 'push_back' a vector of strings.

Or, you can do something like this:

    std::vector<std::vector<std::string>> sample = {{"a", "b"}, {"c", "d"}};
    std::vector<std::vector<std::string>> test;
    // Make 'test' correct dimension
    test.resize(2); //makes 'test' a vector of vectors of size 2
    for (auto &t : test){
      t.resize(2); //makes each element of test (each vector) a vector of size 2
    }
    test[0][0] = sample[0][0];
    std::cout << test[0][0] << "\n";

This is not really a good way of using vectors, but hopefully sheds some light on what's going wrong.

It sort of looks like you only really need a 1D vector - but that's for you to work out, it depends on the rest of the problem.

Also: you don't need #include <bits/stdc++.h>, but you probably want #include <string>

benroberts999
  • 393
  • 1
  • 10