代码之家  ›  专栏  ›  技术社区  ›  ajfbiw.s

C:将strtok令牌分配给char*Segfault

  •  3
  • ajfbiw.s  · 技术社区  · 7 年前

    #include <stdio.h>
    
    int main()
    {
        char * tmp = "0.1";
        char * first = strtok(tmp, ".");
        return 0;
    }
    

    编辑时间:

    #include <stdio.h>
    
    int main()
    {
        char tmp[] = "0.1";
        char *first = strtok(tmp, ".");
        char *second = strtok(tmp, "."); // Yes, should be NULL
        printf("%s\n", first);       
        printf("Hello World\n");
        return 0;
    }
    

    https://www.onlinegdb.com/online_c_compiler

    4 回复  |  直到 7 年前
        1
  •  4
  •   melpomene    7 年前

    第一个代码的问题是 tmp 指向一个只读的字符串文本。什么时候? strtok 试图修改字符串,它崩溃了。


    #include <string.h>
    

    缺少标题意味着 未在程序中声明。C编译器假定所有未声明的函数都返回 int . 对我来说不是这样的 斯特托克 ,返回 char * . 在您的示例中,导致崩溃的可能原因是代码运行在64位计算机上,其中指针的宽度为8字节,但是 内景 只有4个字节。这会弄乱 斯特托克 first 是一个垃圾指针(和 printf 当它试图使用它时崩溃)。

    你可以自己确认一下

    char *first = strtok(tmp, ".");
    printf("%p %p\n", (void *)tmp, (void *)first);
    

    tmp公司 第一 应该是相同的(如果 #include <string.h> ).


    main.c: In function 'main':
    main.c:6:19: warning: implicit declaration of function 'strtok' [-Wimplicit-function-declaration]
         char *first = strtok(tmp, ".");
                       ^
    main.c:6:19: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
    main.c:7:20: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
         char *second = strtok(tmp, "."); // Yes, should be NULL
                        ^
    

    ... onlinegdb将向您显示这些警告,但前提是编译失败!

    因此,要在onlinegdb上看到编译器警告,必须在代码中添加一个硬错误(例如,将 @

        2
  •  3
  •   Nilesh    7 年前

    函数的行为 strtok 是这样的:

    1. 接受字符串 str
    2. 然后strtok函数开始处理给定的字符串 str公司
    3. 如果在到达分隔符字符串之前遇到的字符数为>0,则将分隔符替换为“\n”,并返回指向此迭代中不是分隔符的第一个字符的指针。
    4. 否则,如果在到达分隔符字符串之前遇到的字符数为==0,则继续迭代字符串的其余部分,而不将此分隔符替换为“\n”。

    https://ideone.com/6NCcrR https://ideone.com/KVI5n4 (<-从您的代码中摘录您的代码)

    现在回答你的问题,包括 string.h 标题和设置 char tmp[] = "0.1"; 应该能解决你的问题。

        3
  •  2
  •   user3121023    7 年前

    char * tmp = "0.1"; tmp 指向一个不能修改和删除的字符串文本 strtok 尝试通过替换 . '\0' .

    另一种避免断层的方法是 strchr 找到网点和精度字段,打印出有限数量的字符。子字符串也可以复制到其他变量。

    #include <stdio.h>
    #include <string.h>
    
    int main ( void) {
        char * tmp = "0.1";
        char * first = strchr(tmp, '.');
        char * second = first + 1;
        if ( first) {
            printf ( "%.*s\n", first - tmp, tmp);
            printf ( "%s\n", second);
        }
        printf ( "Hello World\n");
        return 0;
    }
    
        4
  •  0
  •   Suresh Krishna    7 年前

    不是字符串文字

    char*tmp=“0.1”这是一个 .

    字符数组

    故障产生的原因是 函数声明 对于strtok,未找到 字符串.h 不包括,并且gcc或其他c编译器隐式声明 返回类型为int 默认情况下。

    现在取决于平台的整数大小可能会有所不同,如果int size是 4字节 8字节 分别地

    截断 发生在strtok返回的指针地址上,然后在打印时

    如果您可以将strtok的输出类型转换为8字节的类型(在我的例子中是长的),那么就不会有segfault,尽管这不是一种干净的方法。

    包括适当的头文件 避免未定义的行为。