4

我有这个小源代码,用于测试类似于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;
}
4

5 回答 5

4
#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 开始。 is 的第一个元素handhand[0]最后一个元素是hand[2]

于 2013-08-12T09:40:17.947 回答
4

您将一个数组声明hand为具有三个条目,然后使用索引1通过3. 但是 C 中的数组具有从0to的索引size-1(例如2,在您的情况下)。

因此,您在数组范围外写入/读取/读取,导致未定义的行为。

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

于 2013-08-12T09:38:47.013 回答
4

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

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开头

于 2013-08-12T09:39:33.040 回答
1

这是你程序的堆栈:

+-----------------------+
|       ...
|
|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来了

于 2013-08-12T12:39:47.277 回答
0

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

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 中构建并运行结果,都没有得到您意想不到的打印结果。

于 2013-08-12T09:42:08.517 回答