00001: #define BUFFER_SIZE 1<<16 00002: #define ARR_SIZE 1<<16 00003: 00004: void parse_args(char *buffer, char** args, 00005: size_t args_size, size_t *nargs) 00006: { 00007: char *buf_args[args_size]; /* You need C99 */ 00008: char **cp; 00009: char *wbuf; 00010: size_t i, j; 00011: 00012: wbuf=buffer; 00013: buf_args[0]=buffer; 00014: args[0] =buffer; 00015: 00016: for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){ 00017: if ((*cp != '') && (++cp >= &buf_args[args_size])) 00018: break; 00019: } 00020: 00021: for (j=i=0; buf_args[i]!=NULL; i++){ 00022: if(strlen(buf_args[i])>0) 00023: args[j++]=buf_args[i]; 00024: } 00025: 00026: *nargs=j; 00027: args[j]=NULL; 00028: }
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 (because I split some lines) 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.
00001: #include <iostream> 00002: #include <string> 00003: #include <vector> 00004: #include <algorithm> 00005: #include <iterator> 00006: #include <cstdlib> 00007: #include <cerrno> 00008: #include <exception> 00009: #include <unistd.h> 00010: 00011: using std::string; 00012: 00013: void 00014: split_string(const std::string s, 00015: const std::string sep, 00016: std::vector<std::string> &components) 00017: { 00018: typedef std::pair<size_t, size_t> Range; 00019: size_t pos, old_pos; 00020: Range trange; 00021: std::vector<Range> ranges; 00022: trange.first = 0; 00023: trange.second = s.find(sep, trange.first); 00024: if (trange.second == string::npos){ 00025: trange.second = s.length(); 00026: } 00027: ranges.push_back(trange); 00028: while(trange.second < s.length()){ 00029: trange.first = trange.second + 1; 00030: trange.second = s.find(sep, trange.first); 00031: if (trange.second == string::npos){ 00032: trange.second = s.length(); 00033: } 00034: ranges.push_back(trange); 00035: } 00036: 00037: for (int i = 0; i < ranges.size() ; ++i){ 00038: components.push_back(s.substr(ranges[i].first, 00039: ranges[i].second - ranges[i].first) ); 00040: } 00041: } 00042: 00043: class InvalidCommandLine : public std::exception { 00044: 00045: };