1. 题目要求
请实现一个函数,把字符串中每一个空格替换成%20。
2. 题目分析
看似很简单的题目,但是却暗藏了坑。本来空格只占一个位置,但是替换后变成了%20,所以字符串的内存是可变的嘛?覆盖会造成的问题
3. 自己先想一想
我最开始以为这道题目很简单,但是在写代码的时候,在思考的时候,才会有很多看书的时候会忽略的“坑”,而我算运气好还是差呢?几乎把能踩的坑都踩了一遍吧。磕磕绊绊,写出了如下的代码。(里面多余的打印信息只是为了看运行过程而已,没有啥用)
#include <stdio.h>
#include <stdlib.h>
void replaceSpace(char str[],int length)
{
printf("length:%d\n",length);
int i,count=0,end;
for(i=0;i<length;i++)
{
//if(*(str+i)==" ")
if(*(str+i)==' ')
{
count++;
}
}
printf("%d\n",count);
end = length + count * 2;
printf("end:%d\n",end);
char *p1,*p2;
p1= (str+length);
p2= (str+end);
printf("%x\n",p1);
printf("%x\n",p2);
while(p1>str)
{
if( *p1 != ' ')
{
*p2=*p1;
p1--;
p2--;
}else if(*p1 == ' ')
{
*p2='2';
*(p2-1)='0';
*(p2-2)='%';
p1--;
p2=p2-3;
}
}
printf("%s\n",p2);
}
int main()
{
//输入字符串
char str[]="we are happy!";
int len;
len = sizeof(str)+1;
printf("len : %d; sizeof(str) : %d\n",len,sizeof(str));
replaceSpace(str,len);
return 0;
}
最后的运行结果如下图:
3.1 踩过的“坑”
1)在判断的时候没有区分" " 和' '
//if(*(str+i)==" ")
if(*(str+i)==' ')
这个问题还挺严重的,因为这直接导致了count的值,单纯的' ' 是没有\0的,所以count一直是0
2)长度的计算
sizeof不会加上最后的\0的,所以在长度上要加1;
在循环判断的时候,也要分外注意呢!!这些条件是最容易错的地方了
//千万不要写成*p2="%20"!!!,要时刻记得\0的存在
最好动手画一画,关于加加减减的值一定要很注意呢!
while(p1>str)
{
if( *p1 != ' ')
{
*p2=*p1;
p1--;
p2--;
}else if(*p1 == ' ')
{
*p2='0'; //千万不要写成*p2="%20"!!!,要时刻记得\0的存在
*(p2-1)='2';
*(p2-2)='%';
p1--;
p2=p2-3;
}
}
越看越觉得自己应该只是菜鸟阶段吧,只能磕磕绊绊的把功能实现完成,还是看一看大佬的参考代码吧
4. 大佬的参考答案
#include <stdio.h>
#define NULL ((void *)0)
//length是string数组的总容量
//void replaceBlank(char string[],int length)
void replaceBlank(char string[])
{
//if(string == NULL || length <= 0)
//return;
int originalLength=0;
int numberOfBlank=0;
int i = 0;
while(string[i]!='\0')
{
++originalLength;
if(string[i]=' ')
++numberOfBlank;
++i;
}
int newLength=originalLength+numberOfBlank*2;
// if(newLength>length)
// return;
int indexOfOriginal = originalLength;
int indexOfNew = newLength;
while(indexOfOriginal>=0&&indexOfNew > indexOfOriginal)
{
if(string[indexOfOriginal == ' '])
{
string[indexOfNew--]='0';
string[indexOfNew--]='2';
string[indexOfNew--]='%';
}else{
string[indexOfNew--]=string[indexOfOriginal];
}
--indexOfOriginal;
}
}
int main()
{
//输入字符串
char str[]="we are happy!";
//int len=50;
//len = sizeof(str)+1;
//printf("len : %d; sizeof(str) : %d\n",len,sizeof(str));
replaceBlank(str);
return 0;
}
不知道为什么,能编译但无法运行。。。真是奇怪呢?
但大佬的代码有一种高逼格的感觉,是因为他的名字取得比较高级吧。还是有很多值得学习的地方,比如对一些特殊字符串的处理
比如:对空字符串;对连续的空格字符串;对没有字符串的数组;
20190708的更新
class Solution {
public:
void replaceSpace(char *str,int length) {
if(*str == NULL || length == 0)
return;
int count = 0;
int i;
for(i=0;i<length;i++)
{
if(*(str+i)==' ')
count++;
}
//两个指针,一个指向原本的末尾一个指向替换后的末尾
char *p1;
char *p2;
p1 = str+length;
p2 = p1+count*2;
//进行字符串拷贝
while(p1 != p2)
{
if(*p1==' ')
{
*p2 = '0';
*(p2-1) = '2';
*(p2-2) = '%';
p1--;
p2 = p2-3;
}
else
{
*p2 = *p1;
p2--;
p1--;
}
}
}
};
不要相当然的偷懒
比如p2 = p2 -3 写成p2 -3 .....