-1

The program should split input using in each space, then show words in reverse order, it's a problem of codejam.

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

typedef long long int ll;

int main(){
    ll n;
    cin>>n;
    for(ll i=0;i<n;i++){
        string caso;
        getline(cin,caso);
        vector<string>vec;
        for(ll j=0;j<caso.length();j++){
            string ss="";
            if(caso[j]!=' '){
                ss+=caso[j];
            }
            if(caso[j]==' '){
                vec.push_back(ss);
                ss="";
            }
            if(j==caso.length()-1){
                ss+=caso[j];
                vec.push_back(ss);
            }
        }
        for(ll j=vec.size()-1;j>0;j--){
            cout<<vec[j]<<' ';
        }
        cout<<vec[0]<<endl;
    }
    return 0;
}

but it shows me a segmentation fault error

Neon
  • 1
  • 1
  • 1
    Here's [one problem](http://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction). – chris Nov 23 '15 at 00:57

2 Answers2

3

vector.size() returns an unsigned value. If the vector is empty, size() will be 0, so size()-1 will be -1. As an unsigned 32bit number, -1 is 4294967295. So, when the vector is empty (and your code is not protecting itself from that possibility), you end up assigning 4294967295 to j, which a signed 64bit number that can such a value, and so youencounter a segfault trying to access vec[j] when j is an invalid index.

You inner reading loop is not coded correctly in general and needs to be re-written. You are not managing the string data correctly. Try something more like this instead:

#include <iostream>
#include <vector>
#include <string>
#include <limits>

using namespace std;

typedef long long int ll;

int main() {
    ll n;
    if (!(cin >> n)) {
        return 0;
    }
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    for(ll i = 0; i < n; ++i) {
        string caso;
        if (!getline(cin, caso)) {
            break;
        }

        vector<string> vec;
        string ss;

        for(ll j = 0; j < caso.length(); ++j) {
            if (caso[j] != ' ') {
                ss += caso[j];
            }
            else if (!ss.empty()) {
                vec.push_back(ss);
                ss = "";
            }
        }
        if (!ss.empty()) {
            vec.push_back(ss);
        }

        if (!vec.empty()) {
            for(ll j = vec.size()-1; j > 0; --j) {
                cout << vec[j] << ' ';
            }
            cout << vec[0] << endl;
        }
    }

    return 0;
}

That being said, you can simplify the inner reading loop using an istringstream:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <limits>

using namespace std;

typedef long long int ll;

int main() {
    ll n;
    if (!(cin >> n)) {
        return 0;
    }
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    for(ll i = 0; i < n; ++i) {
        string caso;
        if (!getline(cin, caso)) {
            break;
        }

        istringstream iss(caso);
        vector<string> vec;
        string ss;
        while (iss >> ss) {
            vec.push_back(ss);
        }

        for(vector<string>::reverse_iterator it = vec.rbegin(), end = vec.rend(); it != end; ++it) {
            cout << *it << ' ';
        }
        /*
        or:
        reverse(vec.begin(), vec.end()); // #include <algorithm>
        for(vector<string>::iterator it = vec.begin(), end = vec.end(); it != end; ++it) {
            cout << *it << ' ';
        }
        */
    }

    return 0;
}
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
1

If you compile this with warnings enabled, you get

warning: suggest parentheses around assignment used as truth value [-Wparentheses]

at if(j=caso.length()-1).

The = should likely be a ==.

emlai
  • 37,861
  • 9
  • 87
  • 140