parse_args
1: void parse_args(char *buffer, char** args,
2: size_t args_size, size_t *nargs)
3: {
4: char *buf_args[args_size]; /* You need C99 */
5: char **cp;
6: char *wbuf;
7: size_t i, j;
8:
9: wbuf=buffer;
10: buf_args[0]=buffer;
11: args[0] =buffer;
12:
13: for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){
14: if ((*cp != '\0') && (++cp >= &buf_args[args_size]))
15: break;
16: }
17:
18: for (j=i=0; buf_args[i]!=NULL; i++){
19: if(strlen(buf_args[i])>0)
20: args[j++]=buf_args[i];
21: }
22:
23: *nargs=j;
24: args[j]=NULL;
25: }
To understand how it works, I suggest to take a look at the man page of strsep. As you can see this is a lot of code to perform a very simple task.
Compare with
argv = cmd.split()
The C++ version is a bit longer than the C version, but there is less "magic". In fact if you read the code it is very easy to understand how it works. Moreovere there is no hassle with memory allocation.
1:
2: void
3: split_string(const std::string s,
4: const std::string sep,
5: std::vector<std::string> &components)
6: {
7: typedef std::pair<size_t, size_t> Range;
8: size_t pos, old_pos;
9: Range trange;
10: std::vector<Range> ranges;
11: trange.first = 0;
12: trange.second = s.find(sep, trange.first);
13: if (trange.second == string::npos){
14: trange.second = s.length();
15: }
16: ranges.push_back(trange);
17: while(trange.second < s.length()){
18: trange.first = trange.second + 1;
19: trange.second = s.find(sep, trange.first);
20: if (trange.second == string::npos){
21: trange.second = s.length();
22: }
23: ranges.push_back(trange);
24: }
25:
26: for (int i = 0; i < ranges.size() ; ++i){
27: components.push_back(s.substr(ranges[i].first,
28: ranges[i].second - ranges[i].first) );
29: }
30: }
In ObjectiveC there are methods (messages) like componentsSeparatedByString that make the task simpler.