【小练习】C语言双引号形式字符串使用AllTrim()去除空格程序终止问题

       字符串使用前经常使用自定义的AllTrim(char*)函数去除前后冗余空格,贪图方便使用AllTrim(" QRC ");时触发访问未知内存问题,记录如下。

目录

  • 问题背景

  • 问题原因

  • 解决办法

问题背景

       外层函数贪图方便直接传递双引号形式的字符串比如"QRC",内部在实际进行业务处理时习惯性的使用了AllTrim(pInstType);对它进行了处理,结果程序卡住,过几秒后自动退出。

  1. #include <stdio.h>
    #include <string.h>
    
    int DisplayString(char *pInstType);
    void AllTrim(char *str);
    
    int main()
    {
    	int iRet = 0;
    	DisplayString("QRC");
    	return 0;
    }
    
    int DisplayString(char *pInstType)
    {
    	AllTrim(pInstType);
    	printf("Info[%s], size[%d], len[%d]\n", pInstType, sizeof(pInstType), strlen(pInstType));
    	return 0;
    }
    
    void AllTrim(char *str)
    {
    	int i, j, k, h;
    
    	for (i=0; str[i]==' ' && str[i]!='\0'; i++)
    		;	
    	for (j=strlen(str)-1; str[j]==' ' && j>=0; j--)
    		;
    	for (k=0; k<=j-1; k++)
    	{
    		str[k] = str[k+i];
    	}
    	str[k] = '\0';
    
    	while (str[k] != 0)
    	{
    		printf("[LOG_INFO]k=[%d]\n", k);
    		str[k] = 0;
    		k++;
    	}
    }

    程序运行异常,要么一直卡住,要么几秒后终止退出​。

标题截图1.程序卡住界面

 

问题原因

void AllTrim(char *str)
{
	int i, j, k, h;

	for (i=0; str[i]==' ' && str[i]!='\0'; i++)
		;
	printf("[LOG_INFO]i=[%d]\n", i);
	
	for (j=strlen(str)-1; str[j]==' ' && j>=0; j--)
		;

	printf("[LOG_INFO]str[1]=[%c]\n", str[1]);

	for (k=0; k<=j-i; k++)
	{
		printf("[LOG_INFO]j-1=[%d], i=[%d], k=[%d]\n", j-1, i, k);
		printf("[LOG_INFO]str[k]=[%c], str[k+i]=[%c]\n", str[k], str[k+i]);
		str[k] = str[k+i]; //问题发生位置
	}
	printf("[LOG_INFO]str[k]=[%c]\n", str[k]);
	str[k] = '\0';

	while (str[k] != 0)
	{
		printf("[LOG_INFO]k=[%d]\n", k);
		str[k] = 0;
		k++;
	}
}

添加打印,​重新执行程序:

截图2.打印定位问题位置 标题

发现问题发生在给字符串赋值的地方。

双引号传进来的字符串不像这样正规定义的字符串变量有自己的存储地址,没有实际合法地址存储,没有申请内存,就直接赋值,导致赋值存储的位置不可知,访问的位置非法的话就可能导致程序异常。

char sInstType[4];
memcpy(sInstType, 0x00, sizeof(sInstType));
memcpy(sInstType, "QRC", sizeof(sInstType)-1);

解决办法

方案1:双引号传进去的值不使用AllTrim()进行去除空格处理。 

方案2:不要偷懒,按步骤申请一个字符数组来存储。

截图3.申请字符数组后处理正常标题

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值