【问题标题】:String parsing in C using strtok使用 strtok 在 C 中解析字符串
【发布时间】:2013-08-12 09:29:23
【问题描述】:

我有这个小源代码,用于测试类似于变量string 的字符串的解析,我需要在其他项目中使用

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


int main (void)
{
    char string[] = "C-AC-2C-3C-BOB";
    char* s;
    char* hand[3];
    char* usr;


    s = (char*) calloc(1, sizeof(char));
    hand[1] = (char*) calloc(3, sizeof(char));
    hand[2] = (char*) calloc(3, sizeof(char));
    hand[3] = (char*) calloc(3, sizeof(char));
    usr = (char*) calloc(21, sizeof(char));

    s = strtok (string,"-");
    hand[1] = strtok (NULL, "-");
    hand[2] = strtok (NULL, "-");
    hand[3] = strtok (NULL, "-");
    usr = strtok (NULL, "\0");

    printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr);

    return 0;
}

问题是我得到这些 3C:AC:2C:3C:BOB 是 printf 而不是 C:AC:2C:3C:BOB 的结果。

-------编辑-----

没有内存泄漏的代码。问题依旧

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


int main (void)
{
    char string[] = "C-AC-2C-3C-BOB";
    char* s;
    char* hand[3];
    char* usr;

    s = strtok (string,"-");
    hand[1] = strtok (NULL, "-");
    hand[2] = strtok (NULL, "-");
    hand[3] = strtok (NULL, "-");
    usr = strtok (NULL, "\0");

    printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr);

    return 0;
}

【问题讨论】:

  • 您的程序中存在内存泄漏。首先分配内存并分配给一组指针,然后用strtok 的结果覆盖这些指针。
  • 好的,用calloc 编辑整个分配部分并不能解决主要问题
  • @ArrigoPierotti 删除所有calloc() 行,然后再次编译并运行
  • @GrijeshChauhan 代码已编辑,但问题仍然存在
  • C 中的数组是 0-base 索引的。

标签: c parsing strtok calloc


【解决方案1】:

您将数组hand 声明为具有三个条目,然后使用索引13 对其进行索引。但是 C 中的数组具有从 0size-1 的索引(例如,在您的情况下为 2)。

所以你写/读到/从数组的范围外,导致未定义的行为。

将数组的索引更改为02,它应该可以正常工作。

【讨论】:

  • Oh frack >_> 没有真正注意到这个愚蠢的错误 >_> 程序现在可以正常工作了,谢谢
【解决方案2】:

在您的代码中,您存在导致运行时未定义行为的索引不足问题:

hand[3] = strtok (NULL, "-"); 
     ^

printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr);
                                                     ^
                                                 wrong index value   

记住数组中的索引值以0开头,根据声明char* hand[3];索引值可以是0到2

【讨论】:

  • Oh frack >_> 没有真正注意到这个愚蠢的错误 >_> 程序现在可以正常工作了,谢谢
  • @ArrigoPierotti 还有一件事是strtok() 修改了输入字符串并将所有分隔符替换为\0
【解决方案3】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main (void)
{
    char string[] = "C-AC-2C-3C-BOB";
    char* s;
    char* hand[3];
    char* usr;

    s = strtok (string,"-");
    hand[0] = strtok (NULL, "-");
    hand[1] = strtok (NULL, "-");
    hand[2] = strtok (NULL, "-");
    usr = strtok (NULL, "\0");

    printf("%s:%s:%s:%s:%s\n", s, hand[0], hand[1], hand[2], usr);

    return 0;
}

您不需要calloc 指针,因为strtok() 将返回一个有效的内存地址(实际上strtok() 修改了字符串并将分隔符替换为空字符)。 另一个问题是数组的索引:在 C 中,索引从 0 开始。hand 的第一个元素是 hand[0],最后一个元素是 hand[2]

【讨论】:

    【解决方案4】:

    这是你程序的堆栈:

    +-----------------------+
    |       ...
    |
    |0x***00 hand[0]
    |
    |
    |           
    |0x***04 hand[1]       
    |
    |
    |     
    |0x***08 hand[2]           
    |                  
    |
    |
    |0x***0C hand[3]    
    |                       <---hander[1] pointer this address    
    |    
    |______  hand[3] end here 
    

    所以hand[3]用地址覆盖了*hand[1],这就是3C

    【讨论】:

      【解决方案5】:

      首先,您应该注释这些行以避免内存泄漏:

      s = (char*) calloc(1, sizeof(char));
      hand[1] = (char*) calloc(3, sizeof(char));
      hand[2] = (char*) calloc(3, sizeof(char));
      hand[3] = (char*) calloc(3, sizeof(char));
      usr = (char*) calloc(21, sizeof(char));
      

      然后,更改代码后,我在 Windows 和 Linux 中构建并运行结果,都没有得到您意想不到的打印结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多