c - strtok() 函数的分隔符数组

标签 c

我想将我的文本分成单词。分隔符是除拉丁字母以外的任何符号。

这里我有循环,填充我的分隔符数组:

for(i = 0; i <= 127; i ++) {
    if(!isalpha(i)) {
        separators = (char*) realloc(separators, (length + 1) * sizeof(char));
        separators[length] = i;
        length ++;
    }
}

然后我在这里使用它:

char text[] = "hello world!";
char** words = NULL;
char* p = strtok(text, separators);
int cnt = 0;

while(p != NULL) {
    words = (char**) realloc(words, (cnt + 1) * sizeof(char*));
    words[cnt] = strdup(p);
    cnt ++;
    p = strtok(NULL, separators);
}

for(i = 0; i < pnt; i ++) {
    printf(" - %d %s\n", i + 1, words[i]);
}

结果有:

-1 hello world!

如果将分隔符数组替换为 ""则效果很好。 数组有什么问题?

最佳答案

循环中 i 的第一个值 0 不是 alpha;因此 0 将作为分隔符数组中的第一个字节存储。

strtok() 期望接收作为 字符串 的分隔符列表,并且 C 中的字符串以零结尾。所以 strtok() 接收到一个以终止符开头的序列,它认为这是一个空列表,根本没有分隔符。

您可以从 1 开始数组以摆脱干扰零:

for (i = 1; i <= 127; i ++) {
  if(!isalpha(i)) {
      separators = (char*) realloc(separators, (length + 1) * sizeof(char));
      separators[length] = i;
      length ++;
  }
}

// then you also need to terminate it, otherwise strtok() will continue reading
// past the end of the array, with unpredictable (but very likely undesirable) results.

separators[length] = 0x0;

您可能还希望只分配一次字符串(您浪费了一些空间,但节省了一些时间);

#define MAX_SEPARATORS 128

separators = (char*) malloc(separators, MAX_SEPARATORS * sizeof(char));
for (i = 1; i < MAX_SEPARATORS; i++) {
  if (!isalpha(i)) {
      separators[length++] = i;
  }
}
separators[length] = 0x0;

关于c - strtok() 函数的分隔符数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21085544/

相关文章:

c - 读取以零开头的 int 并将其存储到 C 中的数组中

c - 使用 getaddrinfo 将 IPv4 地址转换为 IPv6 地址时丢失服务端口

c++ - 我如何用 c 中的 switch 翻转我的语句?

c++ - Libmosquitto 发布不会将所有消息传递到 Azure IoT 中心

iphone - 纵横比 = 背衬宽度/背衬高度?

c - malloc 和 calloc 分配的内存块布局的区别?

c - 指针和字符串?

c - 在我实现 Lamport 的面包店算法时,线程 1 和 2 具有很高的优先级

c - 将动态分配的数组传递给 C 中的函数是按值传递还是按引用传递的实例?

c - 长整数算术中的歧义?