Vector-based Null Cipher Continuing with my series of cipher programs, I hastily wrote a null cipher program, and I was wondering how it could be improved:

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;sstream&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;

std::string getString();
std::vector&lt;std::string&gt; tokenize(const std::string &amp; str);
std::vector&lt;int&gt; getPattern();

int main(){
    std::string input;
    std::vector&lt;std::string&gt; words;
    std::vector&lt;int&gt; pattern;
    do{
        if(words.size() != pattern.size()){
            std::cout &lt;&lt; "\nError: Number of words must be equal to number of integers in pattern.";
        }
        input = getString();
        words = tokenize(input);
        pattern = getPattern();
    } while(words.size() != pattern.size());

    for(int i = 0; i &lt; words.size(); ++i){
        if(words[i].length() &gt; pattern[i]){
            std::string str = words[i];
            std::cout &lt;&lt; str[pattern[i]];
        }
    }

    std::cout &lt;&lt; '\n';
    return 0;
}

std::string getString(){
    std::cout &lt;&lt; "Seperate words with spaces.\nInput string: ";
    std::string input;
    std::getline(std::cin, input);
    return input;
}

std::vector&lt;std::string&gt; tokenize(const std::string &amp; str){
    std::stringstream ss(str);
    std::istream_iterator&lt;std::string&gt; begin(ss);
    std::istream_iterator&lt;std::string&gt; end;
    std::vector&lt;std::string&gt; words(begin, end);
    return words;
}

std::vector&lt;int&gt; getPattern(){
    std::string pattern;
    std::vector&lt;int&gt; intTokenizedPattern;
    bool validPattern;
    do{
        std::cout &lt;&lt; "Seperate positive integers with spaces: ";
        std::getline(std::cin, pattern);
        std::vector&lt;std::string&gt; tokenizedPattern = tokenize(pattern);
        try{
            std::transform(tokenizedPattern.begin(), tokenizedPattern.end(), 
                std::back_inserter(intTokenizedPattern), 
                [](const std::string &amp; str){ return (std::stoi(str) &gt; 0 ? std::stoi(str) - 1 : throw "Input less than one");});
            validPattern = true;
        } catch(...){
            tokenizedPattern.clear();
            intTokenizedPattern.clear();
            validPattern = false;
        }
    } while(!validPattern);

    return intTokenizedPattern;
}


Here is an example input/output:

Seperate words with spaces.
Input string: Susan says Gail lies. Matt lets Susan feel jovial. Elated angry?
Seperate positive integers with spaces: 1 2 3 1 2 3 1 2 3 1 2
SailatSevEn


In the output above, it is deciphered to say "sail at seven" (null ciphers are not used in the modern age of cryptography).

In my program, I verify that the number of elements in the words and pattern vectors is equal. I also verify that the elements in the pattern vector are all actual integers (which is done in the try-catch loop).

I found it interesting that at this time this is the only null cipher program on Code Review, so it could also prove helpful to future viewers.

How can this code be improved?
This seems like a waste of time:

std::vector&lt;std::string&gt; tokenize(const std::string &amp; str){
    std::stringstream ss(str);
    std::istream_iterator&lt;std::string&gt; begin(ss);
    std::istream_iterator&lt;std::string&gt; end;
    std::vector&lt;std::string&gt; words(begin, end);
    return words;
}


The result is used here:

std::vector&lt;std::string&gt; tokenizedPattern = tokenize(pattern);
std::transform(tokenizedPattern.begin(), tokenizedPattern.end(), 
               std::back_inserter(intTokenizedPattern), 
               [](const std::string &amp; str){ return stuff;});


You use an iterator to copy it into a vector so you can get the iterator to use in a standard algorithm. Why not just use the algorithm with the original iterator.

std::stringstream streamPattern(pattern);
std::transform(std::istream_iterator&lt;std::string&gt;{streamPattern},
               std::istream_iterator&lt;std::string&gt;{}, 
               std::back_inserter(intTokenizedPattern), 
               [](const std::string &amp; str){ return stuff;});