Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting some junk returned by a function

I participated in different coding contests and therefore cant use python cause it's too slow on execution time, but i really like the input.split() thing, so i tried to implement my own split. Here is what i came up with:

#include <iostream>
#include <vector>
#include <stack>

using namespace std;

vector<string> splt(string s){
    vector<string> ans={};
    for(int i=0;i<s.size();i++){
        string str="";
        while(s[i]!=' '){
            str+=s[i];
            i++;
        }
        ans.push_back(str);
    }
    return ans;
}

int main(){
    string s;
    getline(cin, s);
    vector<string> ans=splt(s);
    for(auto i:ans)
        cout<<i<<", ";
}

But the vector returned by the function often(but no always) has some junk at the end. Would appreciate any help with correcting my code, as well as some other impementation of splitting a string into an array.

P.S. Sorry if my English is bad, im from Russia and haven't even finished school :)

like image 746
LukaSsS Avatar asked Dec 14 '22 14:12

LukaSsS


2 Answers

In this loop:

    while(s[i]!=' '){
        str+=s[i];
        i++;
    }

You never check whether i is outside the bounds of s and as long as there isn't a ' ' there, i will be incremented beyond the boundary, and the string will be accessed outside of bounds. The behaviour of accessing the string outside of bounds is undefined.

like image 148
eerorika Avatar answered Dec 25 '22 22:12

eerorika


Your inner loop doesn't stop at the end of the string, only when it encounters a space character.
Thus, if your input doesn't end with a space, you're going to index outside the string and have undefined behaviour.
(And when it works, contiguous space characters will result in empty strings, which you probably don't want.)

The most straightforward way to split on whitespace is to use a stream:

#include <sstream>

vector<string> split(string s){
    vector<string> ans;
    istringstream ss(s);
    string word;
    while (ss >> word)
        ans.push_back(word);
    return ans;
}

or

#include <algorithm>
#include <iterator>
#include <sstream>

vector<string> split(string s){
    vector<string> ans;
    istringstream ss(s);
    copy(istream_iterator<string>(ss), istream_iterator<string>(), back_inserter(ans));
    return ans;
}
like image 29
molbdnilo Avatar answered Dec 25 '22 23:12

molbdnilo