解析c命令:char *,char ** confused

时间:2015-04-09 12:59:25

标签: c parsing string-parsing

我读取了char*中保存的c命令(所以基本上是一个"字符串"命令)逐字节。

例如,"echo a; echo b"

假设我有char *wd = (char *)malloc(20);,当我读取一个字节时,存储在wd[i]

如果我看到'e'wd[0]='e'wd[1]='c'wd[2]='h'wd[3]='o'wd[4]='\0'

我设置了word[0]=wd;

然后,重复为wd再次分配空间的循环。 设置wd [0] =' a',wd [1] =' \ 0'和word [1] = wd;

我的代码如下所示:

for(i=0; i<strlen(input);i++)
{
    if(validChar(input[i]))
    {
        printf("valid char:%c\n", input[i])   
        wd[k]=input[i];
        k++;
        cIndex++; 
    }

    else if(input[i]==' ')
    {
        wd[cIndex]='\0';
        printf("wd: %s\n",wd);
        word[wIndex]=wd;
        printf("word %d: %s\n", wIndex, word[wIndex]);
        wIndex++;

       ....
    }
}

问题在于: 当我打印时,word0 = a和word1 = a。

我很困惑,因为c没有字符串,我必须使用char *。 所以当我&#34;复制&#34;字符串,它不是复制内容,而是指针使其值发生变化。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您需要为每个单词分配新内存。你说你这样做了,但你的例子中没有代码。

char *wd;
for(i=0; i<strlen(input);i++)
{
  wd = malloc(20);  // Added line. Allocate a chunk of memory for the next word
  if(validChar(input[i]))
  {
    printf("valid char:%c\n", input[i])   
    wd[k]=input[i];
    ...

请注意,如果输入包含长度超过19个字节的字,则此代码将遭受缓冲区溢出。

答案 1 :(得分:0)

示例按strtok_r分隔为单词并按strdup复制单词 (注意:两者都是非标准功能)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void){
    char input[256] = "echo a; echo b";

    int word_max = 256;
    char **word = malloc(word_max * sizeof(*word));
    char *command_p, *com_sp;
    int wIndex = 0;

    command_p = strtok_r(input, ";\n", &com_sp);//separate by ";"
    while(command_p){
        char *wd, *wd_sp;
        wd = strtok_r(command_p, " ", &wd_sp);
        while(wd){
            word[wIndex++] = strdup(wd);//make copy
            if(wIndex == word_max){
                word = realloc(word, (word_max += 8)*sizeof(*word));//check omitted
            }
            wd = strtok_r(NULL, " ", &wd_sp);
        }
        command_p = strtok_r(NULL, ";\n", &com_sp);
    }
    //print & relese
    int i;
    for(i=0; i < wIndex; ++i){
        printf("word %d: %s\n", i, word[i]);
        free(word[i]);
    }
    free(word);
    return 0;
}