<p>检查这个解决方案。用valgrind测试无泄漏。
但是我在free里面实现了打印,你可以自己实现free函数,你可以改进splitter函数来实现更好的解析。在</p>
<pre><code>#include <stdio.h>
#include <stdlib.h>
typedef struct arr {
char** words;
int count;
} uarr;
#define null 0
typedef struct cmdr {
char* command;
char** argv;
int argc;
} cmd;
typedef struct list {
cmd* listcmd;
int count;
} cmdlist;
uarr splitter(char* str, char delim);
cmdlist* getcommandstruct(char* string);
void freecmdlist(cmdlist* cmdl);
int main(int argc, char** argv) {
char input[] = "command1 arg1 arg2 arg3 arg4;command2 arg1 arg2 ;command3 arg1 arg2 arg3;command4 arg1 arg2 arg3";
cmdlist* cmdl = getcommandstruct((char*) input);
//it will free . also i added print logic inside free u can seperate
freecmdlist(cmdl);
free(cmdl);
return (EXIT_SUCCESS);
}
/**
* THIS FUNCTION U CAN USE FOR GETTING STRUCT
* @param string
* @return
*/
cmdlist* getcommandstruct(char* string) {
cmdlist* cmds = null;
cmd* listcmd = null;
uarr resultx = splitter(string, ';');
//lets allocate
if (resultx.count > 0) {
listcmd = (cmd*) malloc(sizeof (cmd) * resultx.count);
memset(listcmd, 0, sizeof (cmd) * resultx.count);
int i = 0;
for (i = 0; i < resultx.count; i++) {
if (resultx.words[i] != null) {
printf("%s\n", resultx.words[i]);
char* def = resultx.words[i];
uarr defres = splitter(def, ' ');
listcmd[i].argc = defres.count - 1;
listcmd[i].command = defres.words[0];
if (defres.count > 1) {
listcmd[i].argv = (char**) malloc(sizeof (char*) *(defres.count - 1));
int j = 0;
for (; j < defres.count - 1; j++) {
listcmd[i].argv[j] = defres.words[j + 1];
}
}
free(defres.words);
free(def);
}
}
cmds = (cmdlist*) malloc(sizeof (cmdlist));
cmds->count = resultx.count;
cmds->listcmd = listcmd;
}
free(resultx.words);
return cmds;
}
uarr splitter(char* str, char delim) {
char* holder = str;
uarr result = {null, 0};
int count = 0;
while (1) {
if (*holder == delim) {
count++;
}
if (*holder == '\0') {
count++;
break;
};
holder++;
}
if (count > 0) {
char** arr = (char**) malloc(sizeof (char*) *count);
result.words = arr;
result.count = count;
//real split
holder = str;
char* begin = holder;
int index = 0;
while (index < count) {
if (*holder == delim || *holder == '\0') {
int size = holder + 1 - begin;
if (size > 1) {
char* dest = (char*) malloc(size);
memcpy(dest, begin, size);
dest[size - 1] = '\0';
arr[index] = dest;
} else {
arr[index] = null;
}
index++;
begin = holder + 1;
}
holder++;
}
}
return result;
}
void freecmdlist(cmdlist* cmdl) {
if (cmdl != null) {
int i = 0;
for (; i < cmdl->count; i++) {
cmd def = cmdl->listcmd[i];
char* defcommand = def.command;
char** defargv = def.argv;
if (defcommand != null)printf("command=%s\n", defcommand);
free(defcommand);
int j = 0;
for (; j < def.argc; j++) {
char* defa = defargv[j];
if (defa != null)printf("arg[%i] = %s\n", j, defa);
free(defa);
}
free(defargv);
}
free(cmdl->listcmd);
}
}
</code></pre>