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

2024-09-29 19:00:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python编码非常熟悉,但现在我必须用C来进行stringparsing

我的意见:

input=“命令1 arg1 args2 arg3;command2 args1 args2 arg3;cmd3 arg1 arg2 arg3”

我的Python解决方案: 在

input = "command1 args1 args2 arg3;command2 args1 args2 args3;command3 arg1 arg2 arg3"
compl = input.split(";")
tmplist =[]
tmpdict = {}

for line in compl:
    spl = line.split()
    tmplist.append(spl)

for l in tmplist:
     first, rest = l[0], l[1:]
     tmpdict[first] = ' '.join(rest)

print tmpdict

#The Output: 
#{'command1': 'args1 args2 arg3', 'command2': 'args1 args2 args3', 'cmd3': 'arg1 arg2 arg3'}

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

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

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

^{pr2}$
  1. 我创建了一个struct char*数组来保存用“;”分隔的cmd+args:

    struct ari{char*value[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;     
  1. 按空间分隔命令和数组并将它们保存在我的结构中:

首先,我添加了一个帮助结构:

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; 

我的输出函数如下所示:

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");  
}    
}

但它只产生垃圾(与python解决方案中的输入相同):
(命令1 arg1 arg2 arg3;命令2 arg1 arg2 arg3;命令3 arg1 arg2 arg3)

命令0:command1 Arg 0=command2 Arg 1=arg1 Arg 2=arg2 Arg 3=arg3 Arg 19=command2 Arg 21=arg1 Arg 22=arg2 Arg 23=arg3 Arg 39=command3 Arg 41=arg1 Arg 42=arg2 Arg 43=arg3 分段故障

所以我希望有人能帮我解决这个问题。在


Tags: 命令forargnullarg3structlolarg1
3条回答

用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测试无泄漏。 但是我在free里面实现了打印,你可以自己实现free函数,你可以改进splitter函数来实现更好的解析。在

#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);
    }

}

相关问题 更多 >

    热门问题