0

Why I can't print third element of my vector ? I'm need a words that will be divided to vector and after that, they will be printed. But my third element of vector isn't showing in the terminal.

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

void divideTextCommand(string txt, vector<string> cmd)
{

    string word = "";
    for (auto x : txt)
        {
            if (x == ' ')
            {
                cmd.push_back(word);
                word = "";
            }
            else
            {
                word = word + x;
            }
        }
        cmd.push_back(word);

}


int main()
{
    cout << "Command:" << endl;
    string textCommand; getline(cin, textCommand);
    vector<string> command;
    cout << " " << endl;
    divideTextCommand(textCommand, command);

    cout << command[2];

    return 0;
}

In my terminal program looks like this

bob@msi:~/Desktop/project$ ./output
Command:
barry jack fred john
 
Segmentation fault (core dumped)
comm2231
  • 13
  • 2
  • Unrelated: writing code like this throws people (me) into a hissy fit: `string textCommand; getline(cin, textCommand);` - Why are those on a single line? Alienating readers of your code is not good practice. – Ted Lyngmo Jun 05 '21 at 00:45

3 Answers3

1

You need to pass cmd by reference:

void divideTextCommand(string txt, vector<string> &cmd)
//                                                ^

As it is, command in main remains empty so accessing element [2] is UB.

But I prefer Fantastic Mr Fox's suggestion - split your words into a locally declared array in divideTextCommand and then return that as the function result. It's more natural and carries no performance penalty.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
1

You are currently not providing a reference to command:

void divideTextCommand(string txt, vector<string> cmd)
                                    // ^ this is a copy, original is not edited

I would suggest you simply return your command:

std::vector<std::string> divideTextCommand(std::string txt) {
    std::vector<std::string> cmd
    ...
    return cmd; // Thanks to RVO, this is no more expensive and is much clearer.
Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
  • 1
    And if you're worried, "OMG! Copying the `vector`! Such a profligate expense!" Know that you are not the first, and some really smart folks came up with [copy elision](https://en.cppreference.com/w/cpp/language/copy_elision) as a result. – user4581301 Jun 05 '21 at 00:55
  • 1
    @user4581301 Those are the best additions ever! Mandatory copy elision or (N)RVO. Next step: Elide the copy/move of an argument to a function from being copied/moved if passed by as a return value - let it be the same entity. – Ted Lyngmo Jun 05 '21 at 01:00
0

In your code, in:

void divideTextCommand(string txt, vector<string> cmd)

the vector<string> cmd inside the function now will only be a copy of the inputed version, and will be stored in a completely different memory location. Therefore, any changes made to cmd inside the function will not reflect back to the original variable. This is called pass by value.

To solve it, you simply use pass by reference, by adding a & before your param:

void divideTextCommand(string txt, vector<string> &cmd)

By doing this we're refering to the address of cmd, and changes will be made to both versions.

Result (with your code, adding the &):

Command:
fred george alex john

alex

More info :