用空格分割字符串

splitting a string by white spaces

在阅读此问题之前,请注意我的问题与学校作业有关。对于这个赋值,我们唯一可以使用的函数是 malloc()。其他一切都必须在不使用其他库的情况下完成。

我正在调用函数 ft_split_whitespaces。此函数将字符串作为输入,并将其 "splits" 转换为单词。单词是分隔的空格、制表符和换行符。

#include <stdio.h>

char **ft_split_whitespaces(char *str);

int main(void)
{
    char *str = "what is";
    char **test = ft_split_whitespaces(str);

} 

关于上面的例子,每个索引的结果应该

test[0] = "what"
test[1] = "is"
test[2] = NULL

但是,我只能打印测试[0]的结果。所有其他索引都不会打印出来显示。这是我认为应该打印函数结果的一些代码示例。

int i = 0;
while(test[i] != NULL)
{
   printf("%s", test[i]);
   i++;
}

当这部分代码是运行时,只有test[0]被打印到输出中。我一直坐在这里试图调试我的代码几个小时。如果有人有空闲时间并且不介意查看我的代码,我将不胜感激。我感觉这可能是我使用 malloc 的方式有问题,但我还是想不通。

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


int     count_whitespaces(char *str)
{
    int space_count;
    int i;

    space_count = 0;
    i = 0;
    while(str[i] != '[=13=]')
    {
        if(str[i] == ' ' || str[i] == 9 || str[i] == '\n')
        {
            if(str[i+1] != ' ' && str[i+1] != 9 && str[i+1] != '\n')
                space_count++;
        }
        i++;
    }
    return (space_count);
}

int     check_whitespace(char c)
{
    if (c == ' ' || c == 9 || c == '\n' || c == '[=13=]')
    {
        return (1);
    }
    else
        return(0);
}

int     count_characters(char *str, int i)
{
    int char_count;

    char_count = 0;
    while(str[i])
    {
        if(str[i+1] != ' ' && str[i+1] != 9 && str[i+1] != '\n')
            char_count++;
        else
            break;
        i++;
    }
    return (char_count);
}

char    **ft_split_whitespaces(char *str)
{
    int     i;
    int     j;
    int     k;
    char    **word;
    int     space;

    i = 0;
    j = 0;
    k = 0;
    word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
    while(str[i] != '[=13=]')
    {
        if (check_whitespace(str[i]) == 1)
            i++;
        else
        {           
            if((word[j] = malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL)
                return (NULL);
            while (check_whitespace(str[i]) == 0)
            {
                word[j][k] = str[i];
                i++;
                k++;
            }
            j++;
        }       
    }
    j++;
    word[j] = NULL;
    j = 0
    return word;
}

所以当我输入完这个问题时,我实际上弄清楚了我的代码出了什么问题(感谢堆栈溢出!)。我决定 post 无论如何,因为我认为这对于像我这样的编码新手来说可能是一个很好的学习经验。

这就是我的问题所在。

word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
    while(str[i] != '[=10=]')
    {
        if (check_whitespace(str[i]) == 1)
            i++;
        else
        {           
            if((word[j] = malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL)
                return (NULL);
            while (check_whitespace(str[i]) == 0)
            {
                word[j][k] = str[i];
                i++;
                k++;
            }
            j++;
        }       
    }

我使用以下代码在 while 循环之外分配了我的 char **word

word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));

然后在实际的 while 循环中,我使用

再次 malloc 了它
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));

对同一个变量多次使用 malloc 会导致各种奇怪的问题。所以在 while 循环中,我最终使用了一个声明为 char *words 的新变量。这是带有正确代码的 while 循环部分。

word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
    while(str[i] != '[=13=]')
    {
        if (check_whitespace(str[i]) == 1)
            i++;
        else
        {           
            words = malloc(sizeof(char) * (count_characters(str, i) + 1));
            k = 0;
            while (check_whitespace(str[i]) == 0)
            {
                words[k] = str[i];
                i++;
                k++;
            }
            words[k] = '[=13=]';
            word[j] = words;
            j++;
        }       
    }

您忘记重置 kft_split_whitespaces 中的外部 while 循环应该是这样的

  while (str[i] != '[=10=]') {
    if (check_whitespace(str[i]) == 1){
      i++;
    }
    else {
      if ((word[j] =
           malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL){
        return (NULL);
      }
      while (check_whitespace(str[i]) == 0) {
        word[j][k] = str[i];
        i++;
        k++;
      }
      word[j][k] = '[=10=]';
      j++;
      k = 0;             // reset k
    }
  }