如何修复使用 strtok 后打印的乱码

How to fix gibberish printed after use strtok

我有一个uni项目,我需要检查语法是否正确。我得到一个指向字符串的指针,并检查第一个标记是否可以接受。万一没事,我就往前走。但是万一不行,我需要打印出错误的地方。

我所做的是创建一个缓冲区,因为我无法更改原始字符串。 然后我用strtok切缓冲区,看看我得到的令牌是否可以接受。

char *str = "sz = 12345";
printf("The check of MACRO: %d\n", isMacro(str));

int isMacro(char *str)
{
    char buf = NULL;
    char *token;
    strcpy(&buf,str);
    token = strtok(&buf," ");
    printf("You here, value token is %s\n",token);
}

我预计 printf 会打印 'sz' 但它会打印:

You here, value str is sz<▒R
    char buf = NULL;

这是类型错误。 buf 是单个字符,而 NULL 是指针值。您不能将指针存储在 char.

    strcpy(&buf,str);

此代码具有未定义的行为(除非 str 恰好是一个空字符串)。 buf 不是缓冲区,它是一个单独的 char,因此它没有空间存储整个字符串。

如果你想复制一个字符串,你需要为它的所有字符分配足够的内存:

  1. 您可以使用 strdup(在 POSIX 中,但不是标准 C):

    char *buf = strdup(str);
    if (!buf) {
        ... handle error ...
    }
    ...
    free(buf);
    
  2. 您可以手动复制 strdup

    char *buf = malloc(strlen(str) + 1);
    if (!buf) {
        ... handle error ...
    }
    strcpy(buf, str);
    ...
    free(buf);
    
  3. 你可以使用可变长度数组(但你受限于你的堆栈大小,你无法检查错误):

    char buf[strlen(str) + 1];
    strcpy(buf, str);
    ...
    

buf 是单个 char 而不是 pointerchar。事实上,如果您打算执行 strcpy 将字符串复制到其中,您需要先使用 malloc 分配内存。相反,我建议您使用 strdup 之类的函数而不是 strcpy 来创建原始字符串的副本,以使用 strtok 修改它。记得稍后 free strduped 字符串。

像这样。

int isMacro(char *str)
{
    char *buf = NULL;
    char *token;
    buf = strdup(str);
    token = strtok(buf," ");
    printf("You here, value of token is %s\n",token);
    free(buf);
}