Splitting String in half?

Ok. So here is my problem.
I have a program that needs to take input in the form of:

"COMMAND VALUE"

What I need to do is store each part of the input string in to separate string variables. for the sake of argument I would call these inputA(COMMAND) and inputB(VALUE).

I have extensively looked at strtok(), and input stream solutions. Neither of which appear to be very elegant solutions. (for example strtok requires using char[] pointers?).

Which would even be the better solution for me? Performance isn't really an issue.

All I want is to cut the string in to two w/ a space delimiter. Surely there is a simple and clean solution to this?

Perhaps I need further explanation?

Any assistance on this would be great, thanks.
Last edited on
Sorry, I was going to suggest a istringstream based solution, but I now see you'd prefer something else.

If it's just two substrings separated by a space, then you could use string::find() + string::subst()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
using namespace std;

int main() {
    string cmd = "HELLO WORLD";
    string arg;

    string::size_type pos = cmd.find(' ');
    if(cmd.npos != pos) {
        arg = cmd.substr(pos + 1);
        cmd = cmd.substr(0, pos);
    }

    cout << cmd << "\n";
    cout << arg << "\n";

    return 0;
}


HELLO
WORLD


which could be factored to

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
using namespace std;

// val is passed by value
pair<string, string> splitInTwo(string val) {
    string arg;
    string::size_type pos = val.find(' ');
    if(val.npos != pos) {
        arg = val.substr(pos + 1);
        val = val.substr(0, pos);
    }
    return make_pair(val, arg);
}

int main() {
    string cmd = "HELLO WORLD";

    pair<string, string> pr = splitInTwo(cmd);

    cout << pr.first  << "\n";
    cout << pr.second << "\n";

    return 0;
}

or you could use two string out params, instead of the pair.

If you want to allow for tabs as well as spaces, then you could use string::find_first_of instead of string::find.

And if there might be extra spaces, you'd need to trim the strings, too.

Andy
Last edited on
Oh nice, that looks like a very clean solution. Thanks.
That's just rewriting what the ifstream's >> operator already does.
How can that be better than using streams ?

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
    std::string cmd, arg;
    std::cin >> cmd >> arg;
    std::cout << cmd << '\n' << arg << '\n';

    return 0;
}



hello world
hello
world
ok, well i dove in to some code and tried to make this work in my program.

I am trying to pass some variables by reference in to a static method to split the input in to "Command" and "Argument".

For some reason, the referenced variables (Argument, Command) are not being modified at all.

Here is my code:

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <cstdlib>
#include <iostream>
#include <map>       //stl map container
#include <string>
#include "queue.cpp" //queue class
#include "parse.h" //static class for parsing the commands.

int main(void)
{

    //init input variables
    std::string input="";
    std::string Command="DEFAULT";
    std::string Argument="DEFAULT";
    
    //create associative array (stl map contianer) for user defined vars
    std::map<std::string,std::string>variables;

    
    while ( Command!="GO" ){
          
        //echo out Command and Argument...TESTING
        std::cout<<"Command: " <<Command <<std::endl;
        std::cout<<"Argument: " <<Argument <<std::endl;

          
        std::cout<<"Please enter a command: ";
        std::cin>>input;
        
        //parse the input in to 2 parts ( Command + Argument)
        parse::input(input, Command, Argument);    
        
...



parse.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef PARSE_H
#define PARSE_H

#include<string>

class parse
{
        public:
               //constructor
               parse();  
				
		       //destructor
		       ~parse();
		
		       //other methods 
	           static bool validate(std::string);
	           static void input(std::string&, std::string&, std::string&);
		       static double result(std::string);
		       
};

#endif // PARSE_H 



parse.cpp
1
2
3
4
5
6
7
8
9
10
void parse::input(std::string &input, std::string &Command, std::string &Argument ) {
    
    std::string::size_type pos = input.find(' ');
    if(input.npos != pos)
    {
        Command = input.substr(pos + 1);
        Argument = input.substr(0, pos);
    }
}
So far, I have been able to narrow it down that this if statement is not being hit:

1
2
3
4
5
6
if(input.npos != pos)
    {
//can't get here?!?
        Command = input.substr(pos + 1);
        Argument = input.substr(0, pos);
    }
nvm, i got it. It was simply an issue of me using:

std::cin>>input;

instead of

std::getline(std::cin, input);

Topic archived. No new replies allowed.