诸位看官,请看已知下面代码存在什么问题?仔细思考一分钟……
#include <stdio.h>
#include <stdlib.h>
static VOID RemoveTrailZero(CHAR* str)
{
UINT32 len = (UINT32)strlen(str);
UINT32 i;
for (i = len - 1; i >= 0; i--){
if (str[i] != '0') {
break;
}
}
if (str[i] == '.')
{
i--;
}
str[i + 1] = '\0';
}
#include <stdio.h>
#include <string.h>
#define MAX_STRING_LENGTH 100
static VOID RemoveTrailZero(CHAR* str);
int main() {
CHAR testStr1[MAX_STRING_LENGTH] = "12345000";
CHAR testStr2[MAX_STRING_LENGTH] = "12345.000";
CHAR testStr3[MAX_STRING_LENGTH] = "0.00012345";
CHAR testStr4[MAX_STRING_LENGTH] = "0000";
CHAR testStr5[MAX_STRING_LENGTH] = "12345";
RemoveTrailZero(testStr1);
RemoveTrailZero(testStr2);
RemoveTrailZero(testStr3);
RemoveTrailZero(testStr4);
RemoveTrailZero(testStr5);
printf("Test String 1: %s\n", testStr1); // 应输出 "12345"
printf("Test String 2: %s\n", testStr2); // 应输出 "12345."
printf("Test String 3: %s\n", testStr3); // 应输出 "0.00012345"
printf("Test String 4: %s\n", testStr4); // 应输出 ""
printf("Test String 5: %s\n", testStr5); // 应输出 "12345"
return 0;
}
大家可以把折段代码放到vs2019或者其他编译器中运行看会出现啥问题,这里我就不打哑谜了,请看vs2019中的提示
从中我们可以知道UINT32的变量i会陷入死循环,当i = 0之后,再执行i–之后就会变为4294967295(2^32-1),此后str[i]就会出先数组越界,从而导致程序崩溃。
意识到这个问题就好改代码了,重新修改代码如下
static VOID RemoveTrailZero(CHAR* str)
{
UINT32 len = (UINT32)strlen(str);
INT32 i; // 使用 INT32 类型来避免越界问题
if (len == 0) return; // 如果字符串为空,直接返回
for (i = (INT32)(len - 1); i >= 0; i--) {
if (str[i] != '0') {
break;
}
}
// 检查是否越界
if (i < 0) {
str[0] = '\0'; // 如果所有字符都是0,则清空字符串
} else {
if (str[i] == '.') {
i--; // 如果当前字符是小数点,则跳过它
}
// 确保不会越界
if (i >= 0) {
str[i + 1] = '\0';
}
}
}