【问题标题】:strtok wont accept: char *strstrtok 不接受: char *str
【发布时间】:2011-02-01 13:22:41
【问题描述】:

当使用 char *str 作为第一个参数(不是分隔符字符串)时,strtok 将无法正常工作。

它与以该符号分配字符串的区域有关吗? (据我所知,这是一个只读区域)。

提前致谢

示例:

//char* str ="- This, a sample string.";   // <---doesn't work
char str[] ="- This, a sample string.";   // <---works
char delims[] = " ";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,delims);
while (pch != NULL)
{
  printf ("%s\n",pch);
  pch = strtok (NULL, delims);
}
return 0;

【问题讨论】:

    标签: c string strtok


    【解决方案1】:

    在第一种情况下,您将字符串文字传递给 strtok()。由于 strtok() 修改了此字符串,并且由于无法合法地修改字符串文字,因此您最终会遇到未定义的行为。在第二种情况下,编译器将字符串复制到数组中。数组内容可以修改,所以这段代码就OK了。

    【讨论】:

    • 我明白了。不知道该功能的这种行为。谢谢
    【解决方案2】:

    strtok 修改其第一个参数。

    在您的情况 1 中,strtok 的参数是一个字符串 literal,它不能被修改,因此 strtok 失败。但在情况 2 中,参数是可修改的 char 数组,strtok 修改并分解成更小的字符串。

    【讨论】:

    • 我明白了。好吧,你和其他人非常有帮助,谢谢。
    【解决方案3】:

    这里是一个代码,所有方面都应该被调整。

    • 获取字符指针
    • 使用 strdup 在 strtok_r 中使用 char 指针
    • 使用 strtok_r 实现线程安全
    • 完成后释放结果 strdup,因为它在内部使用了 malloc

    如果我忘记了什么,请给我提示

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define WHITE " \t\n" // white space, tab and newline for tokenizing arguments
    #define MAXARGC 50 // max number of arguments in buf 
    
    void handlecommand(int argc, char *argv[])
    {
        // do some handle code, in this example, just print the arguments
        for(int i = 0; i < argc; i++)
            printf("argv[%d]='%s'\n", i, argv[i]);
    }
    
    void parsecommand(char * cmdstr)
    {
        char *cmdstrdup = strdup(cmdstr);
        if(cmdstrdup == NULL)
          //insuficient memory, do some errorhandling. 
          return; 
        char *saveptr;
        char *ptr;
        char *argv[MAXARGC]; 
        int argc;
    
        if((ptr = strtok_r(cmdstrdup, WHITE, &saveptr)) == NULL)
        {
            printf("%s\n", "no args given");
            return;
        } 
    
        argv[argc = 0] = cmdstrdup;
        while(ptr != NULL) {
            ptr = strtok_r(NULL, WHITE, &saveptr);
            if(++argc >= MAXARGC-1) // -1 for room for NULL at the end
                break;
            argv[argc] = ptr;
        }
    
        // handle command before free
        handlecommand(argc, argv);
    
        // free cmdstrdup, cuz strdup does malloc inside
        free(cmdstrdup);
    }
    
    int main(int argc, char const *argv[])
    {
        parsecommand("command arg1 arg2 arg3\targ4\narg5 arg6  arg7");
        return 0;
    }
    

    结果

    argv[0]='command'
    argv[1]='arg1'
    argv[2]='arg2'
    argv[3]='arg3'
    argv[4]='arg4'
    argv[5]='arg5'
    argv[6]='arg6'
    argv[7]='arg7'
    

    【讨论】:

    • 你的答案有很多不必要的故事,背包,你开始编程的时候等等,你可能会尽量减少它。您还可以处理拼写和大写。我知道您喜欢您正在阅读的这本书,但是使用它提供的头文件会使您的代码示例难以按原样运行,您可能更喜欢标准包含。最后但并非最不重要的一点是,如果你要回答一个 5 年前的问题,不要说你没有测试过你的代码。等了5年,可以再等你测试一下。
    • 感谢您的评论家。删除无用的故事,测试程序,添加所需的标题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 2011-04-21
    • 1970-01-01
    相关资源
    最近更新 更多