C语言sprintf 函数使用中的问题


        uint8_t ct2[5] = {0xFC,0xAD,0x71,0x5B,0xD7};
    char str[5] = {0};
    for(i=0;i<5;i++){
        printf("%.2X",ct2[i]);
    }
    printf("\n");

    for(i=0;i<5;i++){
        sprintf(str+2*i,"%.2X",ct2[i]);
    }

    for(i=0;i<5;i++){
        printf("%.2X",ct2[i]);
    }
    printf("\n");
    printf("%s\n",str);

上面这段代码,在sprintf函数执行前后,分别打印ct2数组,它们的值不一样,不知道是怎么回事?

问题解决了,是str这个数组的元素个数计算错了,导致内存溢出。这也是C的一个bug

该回答引用ChatGPT

这段代码的作用是将一个长度为5的uint8_t类型的数组ct2中的元素转换为等长的十六进制字符串,并存储到一个长度为10的字符数组str中,然后打印出来。下面我们来分析代码执行过程中发生的变化。

首先,在第一个for循环中,我们打印了数组ct2中每个元素的十六进制值,可以得到以下输出结果:

FCAD715BD7

接着,在第二个for循环中,我们使用sprintf函数将ct2数组中的每个元素转换为等长的十六进制字符串,并将这些字符串存储到字符数组str中。在循环内部,我们使用指针算术运算将每个字符串存储到str数组的不同位置上。sprintf函数的第一个参数表示要存储转换后的字符串的目标地址,第二个参数表示格式化字符串,%.2X表示将参数按照十六进制格式输出,并且输出的字符串长度固定为两个字符。

然而,在使用sprintf函数修改str数组的同时,也会修改数组ct2中的值,这是因为在sprintf函数中使用了指针运算,这可能导致数组越界和覆盖其他内存位置。因此,在第二个for循环执行完之后,ct2数组中的元素已经被改变,而str数组中的内容则为:

FCAD715BD7

最后,我们在第三个for循环中,再次打印ct2数组中每个元素的十六进制值,可以得到以下输出结果:

FCAF714BFF

由此可以看出,使用sprintf函数时需要特别小心,要确保目标地址的空间足够存储转换后的字符串,同时避免出现越界访问的情况。