在 C 中实现 Split 函数

Implementing Split function in C

我正在尝试编写一个类似于 Java 中的 split 的 C 函数。当我在 main 做我做的事情时,而不是添加功能,它工作得很好。但是我不明白为什么它不能与添加功能一起使用。

#include <stdio.h>
#include <string.h>
char *words[50] = { NULL };

void add(const char *word) {
    static int i = 0;
    words[i] = word;
    i++;
}


int main( void )
{
    char string[65];
    char *tokenPtr; 

    fgets(string, 65, stdin); 
    tokenPtr = strtok( string, " " ); 
    add(tokenPtr);

    int i = 0;
    while ( tokenPtr != NULL ) {
        add(tokenPtr);
        tokenPtr = strtok( NULL, " " ); 
    }

    int i;
    for(i = 0; words[i] != NULL; i++)
        puts(words[i]);

    return 0; 
} 

这只是我实际代码的一小部分,出于某些原因我需要在另一个函数中执行它。

删除第一个 add 呼叫。

fgets(string, 65, stdin); 
tokenPtr = strtok( string, " " ); 
// add(tokenPtr); // remove

因为您将在下一个 while 循环中添加第一个标记。

此外,您应该删除 int i 的重复项。

// int i; // <-- why is it there?
for(i = 0; words[i] != NULL; i++)
    puts(words[i]);

除了删除对 add 的第一次调用和 i 的重复声明外,还有一些其他注意事项。虽然使用 while 来解析标记没有任何问题,特别是 strtok,但 for 循环可以很好地处理初始调用和每个后续调用 NULL .

类似地,虽然 addistatic 声明没有任何问题,但将索引作为参数传递给函数可以提供对 i 中计数的访问=21=]。如果您以后决定 allocate/reallocate words 动态地增加令牌的确定数量以及灵活性。

虽然在指针上依赖 NULL 测试时使用 for 循环无限迭代没有错,但如果您确实将令牌索引作为参数传递给 add,您可以迭代确定的范围 0 < i < token index 并确保在您拥有 49 令牌的情况下不会尝试读取超出 words 的末尾。 (可以添加测试)

最后,(这只是一个小问题),当声明变量用作正计数器、索引等时,请考虑使用 size_t 而不是 int

解决这个问题的方法有很多种,只要正确,没有比这更正确的。综合考虑,对代码稍作修改可能如下所示:

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

char *words[50] = { NULL };

void add (const char *word, size_t idx) {
    words[idx] = word;
}

int main( void )
{
    char string[65];
    char *tokenPtr; 
    size_t tokIdx = 0;      /* token index  */
    size_t i = 0;           /* use size_t if non-negative counter */

    fgets(string, 65, stdin); 

    for (tokenPtr = strtok (string, " "); tokenPtr && *tokenPtr; tokenPtr = strtok (NULL, " "))
        add (tokenPtr, tokIdx++);

    for (i = 0; i < tokIdx; i++)
        printf (" words[%zu]  %s\n", i, words[i]);

    return 0; 
}

输出

$ echo "how many tokens are in this line eight?" | ./bin/strtokadd
 words[0]  how
 words[1]  many
 words[2]  tokens
 words[3]  are
 words[4]  in
 words[5]  this
 words[6]  line
 words[7]  eight?