从strtok反转令牌会导致字符串为空

问题描述

我试图反转从strtok返回的单词/令牌,我以相反的顺序遍历每个令牌,并将每个ith值分配给称为new的缓冲区。我可以打印令牌指针p的每个ith值/字符,但是由于某种原因,我在分配字符p指向缓冲区new时遇到麻烦。我在这里想念什么或做错什么了?

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

int main(void) {
    char str[] = "This is an example!";
    char *new = malloc(strlen(str));
    char *p = strtok(str," ");
    size_t j = 0;
    while (1) {
        for (size_t i=strlen(p)-1; i>-1; i--) {
            new[j++] = p[i];
        }
        p = strtok(NULL," ");
        if (!p)
            break;
        new[j++] = ' ';
    }
    printf("%s\n",new);
    return 0;
}

标准输出


预期/预期输出

sihT si na !elpmaxe

解决方法

  • 终止的空字符将被添加到缓冲区new中,因为循环的初始值为strlen(p)。应该是strlen(p)-1
  • 为了使i正常工作,ssize_t的类型应为size_t(带符号的类型),而不是i>-1(无符号的类型)。
  • 应为new再分配一个字节,并在字符串的末尾添加终止空字符。

尝试一下:

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

int main(void) {
    char str[] = "This is an example!";
    char *new = malloc(strlen(str)+1); /* allocate one more byte */
    char *p = strtok(str," ");
    size_t j = 0;
    while (1) {
        for (ssize_t i=strlen(p)-1; i>-1; i--) { /* fix loop */
            new[j++] = p[i];
        }
        p = strtok(NULL," ");
        if (!p)
            break;
        new[j++] = ' ';
    }
    new[j] = '\0'; /* add terminating null-character */
    printf("%s\n",new);
    return 0;
}