【问题标题】:Splitting a string into an array of words in C将字符串拆分为C中的单词数组
【发布时间】:2016-09-06 21:07:46
【问题描述】:

我正在尝试创建一个将 cstring 拆分为单词数组的函数。例如。如果我发送“Hello world”,那么我会得到一个包含两个地方的数组,其中第一个地方有元素“Hello”,第二个地方有元素“world”。我遇到了分段错误,我一生都无法弄清楚似乎出了什么问题。

  • 在 for 循环中,我检查有多少空格,这决定了总共有多少单词(间距始终为 N-1,N = 单词数)。然后我告诉程序给计数器加 1(因为 N-1)。

  • 我声明了一个 char* 数组 [],以便将每个单词分开,不确定我是否需要 counter+1(因为 \0?)

  • 这就是棘手的部分。我使用 strtok 来分隔每个单词(使用“”)。然后我 malloc char*array[] 的每个位置,以便它有足够的内存来存储单词。直到没有更多的词可以输入为止。

如果有人能提示我是哪个部分导致了分段错误,我将不胜感激!

void split(char* s){

    int counter = 0;
    int pos = 0;

    for(int i=0; s[i]!='\0'; i++){
        if(s[i] == ' '){
            counter ++;
        }
    }
    counter += 1;

    char* array[counter+1];

    char *token = strtok(s, " ");

    while(token != NULL){
        array[pos] = malloc(strlen(token));
        strcpy(array[pos], token);
        token = strtok(NULL, " ");
        pos++;
    }

【问题讨论】:

  • malloc(strlen(token)) --> malloc(strlen(token)+1)
  • 为了找到失败的地方,a) 在调试器下运行,b) 使用 valgrind(如果使用 linux)
  • c) 像理智的人一样添加打印语句

标签: c arrays string split


【解决方案1】:

如果我发送“Hello world”,那么我会得到一个包含两个位置的数组 第一名的元素是“Hello”,第二个是“world”。

没有。您不能将字符串文字传递给该函数。因为strtok() 修改了它的输入。因此,它会尝试修改字符串文字,从而产生undefined behaviour。

注意strtok() 的限制。来自strtok()的手册页:

   Be cautious when using these functions.  If you do use them, note
   that:

   * These functions modify their first argument.

   * These functions cannot be used on constant strings.

   * The identity of the delimiting byte is lost.

   * The strtok() function uses a static buffer while parsing, so it's
     not thread safe.  Use strtok_r() if this matters to you.

所以,如果你想使用strtok(),你需要传递一个指向可修改内存位置的指针。


正如 BLUPIXY 指出的那样,您的 malloc() 调用没有分配足够的空间。您需要比字符串长度多一个字节(用于终止 nul 字节)。

【讨论】:

  • 传递一个指向可修改内存位置的指针?你能举个例子吗?我以为 char* s(参数)已经是一个指针
  • 例如:传递一个数组。 char arr[] = "Hello world"; split(arr);
  • 哦,我明白了。我将对此进行试验,然后报告进展情况!
  • 伙计,非常感谢您的帮助!我能够通过将数组传递给 split 函数来解决问题。几个问题:当你写“字符串文字”时,这是否意味着我不能写“split(“hello world)”,而是我需要创建一个变量来存储字符串,然后将变量发送到split() 函数?
  • char arr[] = "Hello world"; 复制它。但是,如果您有char *p = "hello world"; split(arr);,您将遇到完全相同的问题。所以,它不是传递一个变量,而是你传递的什么。
猜你喜欢
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 2022-01-18
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
相关资源
最近更新 更多