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

C 如何修复使用strtok后打印的乱码,c,string,strtok,C,String,Strtok,我有uni项目,我需要检查语法是否正确。我获取指向字符串的指针,并检查第一个标记是否可接受。如果没事的话,我继续前进。但万一不行,我需要打印出哪里出了问题 我所做的是创建一个缓冲区,因为我无法更改原始字符串。 之后,我使用strtok剪切缓冲区,看看我得到的令牌是否可以接受 char *str = "sz = 12345"; printf("The check of MACRO: %d\n", isMacro(str)); int isMacro(char *str) { char b

我有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',但它会打印:

你在这里,str值是sz
这是一个类型错误
buf
是单个字符,但
NULL
是指针值。不能将指针存储在
字符中

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

如果要复制字符串,需要为其所有字符分配足够的内存:

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

  • 您可以手动复制
    strdup

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


  • buf
    是单个
    char
    而不是指向
    char
    指针。事实上,如果您计划执行strcpy将字符串复制到它,那么首先需要使用malloc分配内存。相反,我建议您使用类似于
    strdup
    的函数而不是
    strcpy
    来创建原始字符串的副本,以便使用strtok对其进行修改。请记住以后释放
    字符串

    像这样的

    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);
    }
    

    为什么
    char buf=NULL
    甚至可以编译?@Ayxan在某些平台上
    NULL
    被定义为
    0
    ,而不是
    ((void*)0)
    ,因此代码实际上变成了
    buf='\0'
    。其他编译器将(某些)类型错误视为可选警告,而不是硬错误。很好的建议,但值得注意的是,
    strdup
    不是c标准库的一部分(它是POSIX),因此一些编译器可能不提供它(在这种情况下,您的
    strlen、malloc
    memcpy
    建议很好)
    isMacro()
    未命中返回值。
    isMacro()
    未命中返回值,因此out
    printf()
    可能会调用未定义的行为。
    char *buf = malloc(strlen(str) + 1);
    if (!buf) {
        ... handle error ...
    }
    strcpy(buf, str);
    ...
    free(buf);
    
    char buf[strlen(str) + 1];
    strcpy(buf, str);
    ...
    
    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);
    }