簡體   English   中英

Function 拆分字符串並將字符串中的每個單詞作為字符串數組返回

[英]Function to split a string and return every word in the string as an array of strings

我正在嘗試創建一個 function 將接受一個字符串,並返回字符串中的單詞數組。 這是我的嘗試:

#include "main.h"

/**
 * str_split - Splits a string
 * @str: The string that will be splited
 * 
 * Return: On success, it returns the new array
 * of strings. On failure, it returns NULL
 */
char **str_split(char *str)
{   
    char *piece, **str_arr = NULL, *str_cpy;
    int number_of_words = 0, i;

    if (str == NULL)
    {
        return (NULL);
    }
    str_cpy = str;
    piece = strtok(str_cpy, " ");
    while (piece != NULL)
    {
        if ((*piece) == '\n')
        {
            piece = strtok(NULL, " ");
            continue;
        }
        number_of_words++;
        piece = strtok(NULL, " ");
    }
    
    str_arr = (char **)malloc(sizeof(char *) * number_of_words);
    piece = strtok(str, " ");
    for (i = 0; piece != NULL; i++)
    {
        if ((*piece) == '\n')
        {
            piece = strtok(NULL, " ");
            continue;
        }
        str_arr[i] = (char *)malloc(sizeof(char) * (strlen(piece) + 1));
        strcpy(str_arr[i], piece);
        piece = strtok(NULL, " ");
    }
    return (str_arr);
}

一旦我編譯了我的文件,我應該得到:

Hello
World

但我得到:

Hello

為什么會這樣? 我試圖通過遍歷原始字符串的副本並跟蹤字數來為新字符串數組動態分配 memory。 發生這種情況是因為分配給字符串數組的空間不夠嗎?

代碼總體上看起來不錯,只有一些問題:

您嘗試復制str ,因為strtok在解析時對其進行了修改。 這是正確的做法。 但是,以下行是錯誤的:

str_cpy = str;

這不是字符串的副本,它只是復制字符串的地址。 您可以在此處使用strdup function。

此外,您需要返回計算的字數,否則調用者將不知道解析了多少字。

最后,在定義要傳遞給此 function 的字符串時要小心。 如果你用以下方式調用它:

char **arr = str_split ("Hello World", &nwords);

甚至有:

char *str = "Hello World";
char **arr = str_split (str, &nwords);

程序將崩潰,因為這里的str是只讀的(參見this )。

考慮到這些,該程序應與:

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

/**
 * str_split - Splits a string
 * @str: The string that will be splited
 * 
 * Return: On success, it returns the new array
 * of strings. On failure, it returns NULL
 */
char **str_split(char *str, int *number_of_words)
{
    char *piece, **str_arr = NULL, *str_cpy = NULL;
    int i = 0;

    if (str == NULL)
    {
        return (NULL);
    }
    str_cpy = strdup (str);
    piece = strtok(str_cpy, " ");
    while (piece != NULL)
    {
        if ((*piece) == '\n')
        {
            piece = strtok(NULL, " ");
            continue;
        }
        (*number_of_words)++;
        piece = strtok(NULL, " ");
    }

    str_arr = (char **)malloc(sizeof(char *) * (*number_of_words));
    piece = strtok(str, " ");
    for (i = 0; piece != NULL; i++)
    {
        if ((*piece) == '\n')
        {
            piece = strtok(NULL, " ");
            continue;
        }
        str_arr[i] = (char *)malloc(sizeof(char) * (strlen(piece) + 1));
        strcpy(str_arr[i], piece);
        piece = strtok(NULL, " ");
    }

    if (str_cpy)
        free (str_cpy);

    return (str_arr);
}

int main ()
{
    int nwords = 0;
    char str[] = "Hello World";

    char **arr = str_split (str, &nwords);

    for (int i = 0; i < nwords; i++) {

        printf ("word %d: %s\n", i, arr[i]);
    }

    // Needs to free allocated memory...
}

測試:

$ gcc main.c && ./a.out 
word 0: Hello
word 1: World

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM