Python 在C中解析字符串并将其保存到结构数组中

Python 在C中解析字符串并将其保存到结构数组中,python,c,string,parsing,Python,C,String,Parsing,我非常熟悉Python编码,但现在我必须用C语言进行字符串解析 我的意见: input=“command1 args1 args2 arg3;command2 args1 args2 args3;cmd3 arg1 arg2 arg3” 我的Python解决方案: 预期输出:Dict,命令作为键,参数作为字符串连接在值中 到目前为止,我的C解决方案: 我想将命令和参数保存在结构中,如下所示: struct cmdr{ char* command; char* args[19];

我非常熟悉Python编码,但现在我必须用C语言进行字符串解析

我的意见:

input=“command1 args1 args2 arg3;command2 args1 args2 args3;cmd3 arg1 arg2 arg3”

我的Python解决方案:

预期输出:Dict,命令作为键,参数作为字符串连接在值中

到目前为止,我的C解决方案:

我想将命令和参数保存在结构中,如下所示:

struct cmdr{
    char* command;
    char* args[19];
};
void output(struct arraycmd b){ 
int i;
int j;

for(i=0; i<200;i++){
     if (b.lol[i].command != NULL){
        printf("Command %d: %s",i,b.lol[i].command);
    }
    for (j = 0; j < 200;j++){
        if  (b.lol[i].args[j] != NULL){
            printf(" Arg %d = %s",j,b.lol[i].args[j]);
        }
    }   
    printf(" \n");  
}    
}
  • 我制作了一个struct char*数组来保存cmd+args,以“;”分隔:

    结构ari{char*值[200];}

  • 职能:

    struct ari inputParser(char* string){
        char delimiter[] = ";";
        char *ptrsemi;  
        int i = 0;
        struct ari sepcmds;
        ptrsemi = strtok(string, delimiter);
    
        while(ptrsemi != NULL) {
            sepcmds.value[i] = ptrsemi;
            ptrsemi = strtok(NULL, delimiter);
            i++;
    
        }
    return sepcmds;     
    
  • 按空格分隔命令和数组,并将它们保存在my struct中:
  • 首先,我添加了一个帮助结构:

    struct arraycmd {
    struct cmdr lol[10];
    };
    
    
    
    struct arraycmd parseargs (struct ari z){
        struct arraycmd result;
        char * pch;
        int i;
        int j = 0;
    
        for (i=0; i < 200;i++){
             j = 0;
             if (z.value[i] == NULL){
                   break;
                 }
                pch = strtok(z.value[i]," ");
        while(pch != NULL) {
            if (j == 0){
                result.lol[i].command = pch;    
                pch = strtok(NULL, " ");
                j++;
            } else {
            result.lol[i].args[j]= pch;
            pch = strtok(NULL, " ");
            j++;
            }
        }
        pch = strtok(NULL, " ");
          }
             return result; 
    
    struct arraycmd{
    struct-cmdr-lol[10];
    };
    结构arraycmd parseargs(结构Ariz){
    结构arraycmd结果;
    char*pch;
    int i;
    int j=0;
    对于(i=0;i<200;i++){
    j=0;
    if(z.value[i]==NULL){
    打破
    }
    pch=strtok(z.值[i],“”);
    while(pch!=NULL){
    如果(j==0){
    result.lol[i].command=pch;
    pch=strtok(空,“”);
    j++;
    }否则{
    result.lol[i].args[j]=pch;
    pch=strtok(空,“”);
    j++;
    }
    }
    pch=strtok(空,“”);
    }
    返回结果;
    
    我的输出函数如下所示:

    struct cmdr{
        char* command;
        char* args[19];
    };
    
    void output(struct arraycmd b){ 
    int i;
    int j;
    
    for(i=0; i<200;i++){
         if (b.lol[i].command != NULL){
            printf("Command %d: %s",i,b.lol[i].command);
        }
        for (j = 0; j < 200;j++){
            if  (b.lol[i].args[j] != NULL){
                printf(" Arg %d = %s",j,b.lol[i].args[j]);
            }
        }   
        printf(" \n");  
    }    
    }
    
    void输出(struct arraycmd b){
    int i;
    int j;
    
    对于(i=0;i来说,在python中直接获取C逻辑可能更容易。这更接近于C,您可以尝试将其音译为C。您可以使用
    strncpy
    提取字符串并将其复制到您的结构中

    str = "command1 args1 args2 arg3;command2 args1 args2 args3;command3 arg1 arg2 arg3\000"
    
    start = 0
    state = 'in_command'
    
    structs = []
    
    command = ''
    args = []
    for i in xrange(len(str)):
        ch = str[i]
        if ch == ' ' or ch == ';' or ch == '\0':
            if state == 'in_command':
                command = str[start:i]
            elif state == 'in_args':
                arg = str[start:i]
                args.append(arg)
            state = 'in_args'
            start = i + 1
        if ch == ';' or ch == '\0':
            state = 'in_command'
            structs.append((command, args))
            command = ''
            args = []
    
    for s in structs:
        print s
    

    您的问题是,您依赖于将结构中的指针初始化为NULL

    它们只是随机值,因此是SEGV


    当结构只有10个命令和19个参数时,您还打印了200个命令和200个参数。

    检查此解决方案。使用valgrind进行测试,无泄漏。 但我在freeing中实现了打印。你可以通过查看free函数自己实现。进一步,你可以改进拆分器函数以实现更好的解析

    #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);
        }
    
    }
    
    #包括
    #包括
    typedef结构arr{
    字符**字;
    整数计数;
    }uarr;
    #定义空0
    类型定义结构cmdr{
    char*命令;
    字符**argv;
    int-argc;
    }cmd;
    类型定义结构列表{
    cmd*listcmd;
    整数计数;
    }cmdlist;
    uarr拆分器(char*str,char-delim);
    cmdlist*getcommandstruct(字符*字符串);
    作废freecmdlist(cmdlist*cmdl);
    int main(int argc,字符**argv){
    字符输入[]=“command1 arg1 arg2 arg3 arg4;command2 arg1 arg2;command3 arg1 arg2 arg3;command4 arg1 arg2 arg3”;
    cmdlist*cmdl=getcommandstruct((char*)输入;
    //它将免费。我还添加了打印逻辑内免费你可以分开
    freecmdlist(cmdl);
    免费(cmdl);
    返回(退出成功);
    }
    /**
    *此函数可用于获取结构
    *@param字符串
    *@返回
    */
    cmdlist*getcommandstruct(字符*字符串){
    cmdlist*cmds=null;
    cmd*listcmd=null;
    uarr resultx=拆分器(字符串“;”);
    //让我们分配
    如果(resultx.count>0){
    listcmd=(cmd*)malloc(sizeof(cmd)*resultx.count);
    memset(listcmd,0,sizeof(cmd)*resultx.count);
    int i=0;
    对于(i=0;i1){
    listcmd[i].argv=(char**)malloc(sizeof(char*)*(defres.count-1));
    int j=0;
    对于(;jcount=resultx.count;
    cmds->listcmd=listcmd;
    }
    免费(resultx.words);
    返回CMD;
    }
    uarr拆分器(char*str,char-delim){
    char*holder=str;
    uarr结果={null,0};
    整数计数=0;
    而(1){
    如果(*持有人==delim){
    计数++;
    }
    如果(*holder=='\0'){
    计数++;
    打破
    };
    holder++;
    }
    如果(计数>0){
    char**arr=(char**)malloc(sizeof(char*)*计数);
    result.words=arr;
    result.count=计数;
    //真正的分裂
    holder=str;
    char*begin=holder;
    int指数=0;
    while(索引<计数){
    如果(*holder==delim | |*holder=='\0'){
    int size=保持架+1-开始;
    如果(大小>1){
    char*dest=(char*)malloc(大小);
    memcpy(dest、begin、size);
    dest[size-1]='\0';
    arr[索引]=目的地;
    }否则{
    arr[index]=null;
    }
    索引++;
    开始=保持架+1;
    }
    holder++;
    }
    }
    返回结果;
    }
    作废freecmdlist(cmdlist*cmdl){
    如果(cmdl!=null){
    int i=0;
    对于(;icount;i++){
    cmd def=cmdl->listcmd[i];
    char*defcommand=def.command;
    字符**defargv=def.argv;
    如果(defcommand!=null)printf(“command=%s\n”,defcommand);
    自由(defcommand);
    int j=0;
    对于(;jlistcmd);
    }
    }
    
    您的工作是什么