将c字符串解析为指针数组时出现分段错误

时间:2014-09-11 23:24:02

标签: c arrays pointers segmentation-fault

函数makearg应该计算char数组中的单词数,并将每个单词分解为指针数组中自己的位置。 分段错误似乎是strncpy函数的一个问题。

int makearg(char s[], char ***args);

int main(){

  char **args = (char**)(malloc(100));

  char *str = "ls is a -l file";
  int argc;
  argc = makearg(str, &args);

  printf("%d", argc);
  printf("%c", '\0');

  int i;
  for(i = 0; i < argc; i++){
    puts(args);
    printf("%c", '\n');
  }
  return 0;
}

/////////////////////////////////////////

int makearg(char s[], char ***args){

  int argc = 0;
  int charc = 0;
  int wordstart = 0;

  while(1){
    if(s[charc] == '\0'){
      strncpy(*args[argc], s + wordstart, charc - wordstart);
      args[argc][(charc - wordstart) + 1] = '\0';

      argc++;
      break;
  }

  if(s[charc] == ' '){
    strncpy(*args[argc], s + wordstart, charc - wordstart);
    args[argc][(charc -  wordstart) + 1] = '\0';

    wordstart = charc + 1;
    argc++;
    charc++;
  }

  else{
    charc++;
    }
  }
  return argc;
}

2 个答案:

答案 0 :(得分:1)

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

int makearg(const char s[], char ***args);

int main(void){
    char **args = NULL;
    const char *str = "ls is a -l file";
    int argc = makearg(str, &args);

    printf("argc : %d\n", argc);

    int i;
    for(i = 0; i < argc; i++){
        puts(args[i]);
        free(args[i]);
    }
    free(args);
    return 0;
}

int wordCount(const char *s){
    char prev = ' ';
    int wc = 0;

    while(*s){
        if(isspace(prev) && !isspace(*s)){
            ++wc;
        }
        prev = *s++;
    }
    return wc;
}

int makearg(const char s[], char ***args /*out*/){
    int argc = wordCount(s);
    int len;

    if(argc == 0){
        *args = NULL;
        return 0;
    }
    *args = malloc(argc * sizeof(char*));
    argc = 0;
    while(1){
        while(isspace(*s))
            ++s;
        if(EOF==sscanf(s, "%*s%n", &len))
            break;
        (*args)[argc] = malloc(len + 1);
        strncpy((*args)[argc], s, len);
        (*args)[argc++][len] = '\0';
        s += len;
    }
    return argc;
}

答案 1 :(得分:0)

您为args指针数组分配了空间,但是您永远不会为要存储在其中的字符串分配空间,因此当您尝试将字符串存储在makearg中时,您正在解释无论随机垃圾是什么作为指针,这都不起作用。

另外,你只为指针数组分配100个字节 - 它不清楚有多少 您希望能够分割的单词,但malloc调用可能看起来更像

char **args = malloc(MAX_WORDS * sizeof(char *));  /* no cast required */

然后使用循环执行MAX_WORDS更多malloc次调用,以便使用有效指针初始化args