1

I am trying to accept the input from user where first line will be Integer to indicate number of testcases

if number is 3

Input will be like

3
Hello world
hey there, I am John
have a nice day

I am using getline to read the input

My code

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(){
    int n;
    cin >> n;

    vector<string> arr;

    for(int i=0; i<n; i++){
        string s;
        getline(cin, s);
        arr[i] = s;
    }
}

Error:

3 

Segmentation fault(core dumped)
Sociopath
  • 11,667
  • 16
  • 38
  • 61
  • 6
    `arr[i] = s;` But `arr` is empty, hence it doesn't have `i`th element. If you want to insert into it, you can use [`push_back`](https://en.cppreference.com/w/cpp/container/vector/push_back), or [`emplace_back`](https://en.cppreference.com/w/cpp/container/vector/emplace_back). – Algirdas Preidžius Aug 29 '20 at 15:42
  • @AlgirdasPreidžius thanks!! it was silly mistake from my side – Sociopath Aug 29 '20 at 15:47

2 Answers2

2

arr is an empty vector, so arr[i] = s; is going to access out of bounds. The [] operator does not grow the vector. It can only be used to access already existing elements.

Jesper Juhl
  • 1
  • 3
  • 38
  • 63
1

You can't create an element of a vector using the [] indexing operator; your line arr[i] = s; is trying to assign a string to an element that doesn't (yet) exist.

There are several ways around this: first, you could use the push_back function to add a new element to the end of the vector, in each loop; second, you could use the resize member to pre-allocate a specified number of elements (which you can then use in the arr[i] = s; line); third - and perhaps simplest - you can 'pre-allocate' the elements of the vector by specifying the number of elements in the declaration (constructor), like this:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string> // Need this for the "getline()" function definition

using namespace std;

int main()
{
    size_t n; // Indexes and operations on std::vector use "size_t" rather than "int"
    cin >> n;
    cin.ignore(1); // Without this, there will be a leftover newline in the "cin" stream
//  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // More precise, actually!
    vector<string> arr(n);
//  arr.resize(n); // Alternative to using 'n' in constructor
    for (size_t i = 0; i < n; i++) {
        string s;
        getline(cin, s);
        arr[i] = s;
    }

    for (auto s : arr) cout << s << endl; // Just to confirm the input values
    return 0;
}

There are also a few other issues in your code that I have 'fixed' and commented on in the code I posted. Feel free to ask for further clarification and/or explanation.


EDIT: On the use of the cin.ignore(1); line I added, see Why does std::getline() skip input after a formatted extraction? (and the excellent answers given there) for more details.

Adrian Mole
  • 30,672
  • 69
  • 32
  • 52
  • Can you elaborate `cin.ignore(1); // Without this, there will be a leftover newline in the "cin" stream` this? I think this is the reason I am only able to read 2 lines instead of 3 – Sociopath Aug 29 '20 at 15:58
  • 1
    @Sociopath See the Q/A I linked in my edit - I can't really improve on those posts. – Adrian Mole Aug 29 '20 at 16:01
  • Thank you for your answer and pointing out other optimizations :-) – Sociopath Aug 29 '20 at 16:05
  • 1
    "you could use the reserve member to pre-allocate a specified number of elements (which you can then use in the arr[i] = s" - No. That's wrong. `reserve` just allocates memory so that the vector won't have to do so on each addition. It does *not* make `arr[I] = s;` valid - it does not change the size, only capacity. You cannot access memory that's purely "reserved". You probably meant to say `resize()` which changes *both* the size and capacity of the vector. `reserve` only changes capacity. – Jesper Juhl Aug 29 '20 at 16:46
  • 1
    @JesperJuhl Indeed - my mistake! Now edited to suggest `resize()` instead of `reserve()`. – Adrian Mole Aug 29 '20 at 16:49