编写一个方法来替换C样式字符串中的所有空格

编写一个方法来替换C样式字符串中的所有空格,c,arrays,C,Arrays,我遇到了这个面试问题,希望得到一些帮助来理解它的解决方案: 编写一个方法,用“%20”替换字符串中的所有空格 解决方案(来自论坛): charstr[]=“helo b”; int长度=strlen(str); int spaceCount=0,newLength,i=0; 对于(i=0;i=0;i--){ 如果(str[i]=''){ str[newLength-1]=“0”;/??? str[newLength-2]=“2”; str[newLength-3]='%'; newLength=

我遇到了这个面试问题,希望得到一些帮助来理解它的解决方案:

编写一个方法,用“%20”替换字符串中的所有空格

解决方案(来自论坛):

charstr[]=“helo b”;
int长度=strlen(str);
int spaceCount=0,newLength,i=0;
对于(i=0;i=0;i--){
如果(str[i]=''){
str[newLength-1]=“0”;/???
str[newLength-2]=“2”;
str[newLength-3]='%';
newLength=newLength-3;
}否则{
str[newLength-1]=str[i];
newLength=newLength-1;
}
}

这个程序对我不起作用……我想在深入研究代码之前先了解一下算法。

在我看来,它首先搜索字符串以找到所有空格,然后尝试加长字符串以适应字符串中每个空格的2个额外字符(20)(但我不认为他分配了空格),然后,它再次遍历字符串,但这次是相反的,将每个不是空格的字符放在新字符串的后面,如果遇到空格,它会将%20放在其中,但它的操作是相反的

for (i = 0; i < length; i++) {
    if (str[i] == ' ') {
        spaceCount++; //count spaces...
    }
}
这不能像这样做,您必须分配更多内存,但这里我们扩展了字符串变量的大小。我认为最好是分配一个新变量,因为下一步使用另一个变量会更容易

for (i = length - 1; i >= 0; i--) {
    if(str[i] == ' ') {
        str[newLength - 1] = '0'; //???
        str[newLength - 2] = '2';
        str[newLength - 3] = '%';
        newLength = newLength - 3;
    } else {
        str[newLength - 1] = str[i];
        newLength = newLength - 1;
    }
}
最后,如果字符串被适当地扩展,这一步应该是可行的,但是可以稍微重写一下以使其更清晰

我建议这样做,假设newstr是在前面步骤中分配的新变量:

int j = 0;
for(i = 0; i < length; i++, j++) {
   if(str[i] == ' ') {
      newstr[j] = '%';
      newstr[++j] = '2';
      newstr[++j] = '0';
   } else {
      newstr[j] = str[i];
   }
}

算法是这样的: 首先计算空格的数量。。 假设字符串是“aer t”,这意味着2个空格。。当前长度为6(如果索引为0,则c为5)。。 输出字符串应为“ae%20r%20t”。。长度=10(索引=0时为9) 所以新的长度是6+'2'*2,所以她的长度是10

这是调整长度的方法。。
然后他从反面穿过,一个字符一个字符地放置。。当他遇到空格时,他将%20放在相反的位置,因为他以相反的顺序遍历原始字符串…

该示例被破坏

缓冲区溢出,字符串(strlen)的一次无意义扫描,难以读取

int main() {
  char src[] = "helo b";
  int len = 0, spaces = 0;
  /* Scan through src counting spaces and length at the same time */
  while (src[len]) {
    if (src[len] == ' ')
      ++spaces;
    ++len;
  }
  /* Figure out how much space the new string needs (including 0-term) and allocate it */
  int newLen = len + spaces*2 + 1;
  char * dst = malloc(newLen);
  /* Scan through src and either copy chars or insert %20 in dst */
  int srcIndex=0,dstIndex=0;
  while (src[srcIndex]) {
    if (src[srcIndex] == ' ') {
      dst[dstIndex++]='%';
      dst[dstIndex++]='2';
      dst[dstIndex++]='0';
      ++srcIndex;
    } else {
      dst[dstIndex++] = src[srcIndex++];
    }
  }
  dst[dstIndex] = '\0';
  /* Print the result */
  printf("New string: '%s'\n", dst);
  /* And clean up */
  free(dst);
  return 0;
}
/*用“%20”替换空格的程序*/
/*作者senthilkumar M*/
eg str=“ab cd ef”
str1=“ab%20cd%20ef”
字符*空格_替换(字符*str)
{
int l=strlen(str);
int i=0,j=0;
int spc=0,nl=0;
char*str1=NULL;
对于(i=0;i
嗯,如果这是C,那么它就坏了。它不会为结果分配更多内存。是的……它试图调整静态数组的大小……但是,再说一遍……解决这个问题的正确算法是什么?我已经编译并尝试了这个;它是有效的。但它是破碎和危险的,因为你踩到了其他记忆场所的脚趾。不要做这种事;如果您在运行时需要更多的位置,您迟早要使用
malloc
。如何将字符串的剩余部分进一步复制3个位置并插入%20?我用另一个解决方案编辑了我的答案。。。但实际上,我认为如果字符串被正确扩展,给定的代码可能会工作。那么你是说,如果我们动态分配数组并正确扩展它,原始代码会工作?我没有测试它,但我认为它应该工作。对您的问题的注释指出了相同的方向。这是有效的…(我们需要在打印新字符串之前添加dst[dstIndex]='\0!)此解决方案分配第二个字符数组,它可以在不保留反向循环并正确扩展第一个循环的情况下完成。@Krtek:不,它不能,原始的str[]没有足够的空间放置“helo%20b”@maxpayne:缺少\0是我在粘贴之前将calloc更改为malloc得到的。已编辑并修复:)@Muggen:No。原始空间在len变量中计数。新的“空间”需要2个额外的字符。“”需要
1(len)+1(空格)*2+1(0术语)
chars才能完全适合“%20\0”
int j = 0;
for(i = 0; i < length; i++, j++) {
   if(str[i] == ' ') {
      newstr[j] = '%';
      newstr[++j] = '2';
      newstr[++j] = '0';
   } else {
      newstr[j] = str[i];
   }
}
for (i = length - 1, j = newLength - 1; i >= 0; i--, j--) {
    if(str[i] == ' ') {
        str[j] = '0';
        str[--j] = '2';
        str[--j] = '%';
    } else {
        str[j] = str[i];
    }
}
int main() {
  char src[] = "helo b";
  int len = 0, spaces = 0;
  /* Scan through src counting spaces and length at the same time */
  while (src[len]) {
    if (src[len] == ' ')
      ++spaces;
    ++len;
  }
  /* Figure out how much space the new string needs (including 0-term) and allocate it */
  int newLen = len + spaces*2 + 1;
  char * dst = malloc(newLen);
  /* Scan through src and either copy chars or insert %20 in dst */
  int srcIndex=0,dstIndex=0;
  while (src[srcIndex]) {
    if (src[srcIndex] == ' ') {
      dst[dstIndex++]='%';
      dst[dstIndex++]='2';
      dst[dstIndex++]='0';
      ++srcIndex;
    } else {
      dst[dstIndex++] = src[srcIndex++];
    }
  }
  dst[dstIndex] = '\0';
  /* Print the result */
  printf("New string: '%s'\n", dst);
  /* And clean up */
  free(dst);
  return 0;
}
/* program to replace the space with "%20" */
/* Author senthilkumar M */

eg str = "ab cd ef"
   str1 = "ab%20cd%20ef"


char *space_replace(char *str)
{
        int l = strlen(str);
        int i = 0, j =0;
        int spc = 0, nl = 0;
        char *str1 = NULL;

        for(i = 0; i < l; i++)  {
                if(str[i] == ' ') {
                        spc++;
                }
        }
        nl = l + 2*spc + 1;
        str1 = (char *) malloc(sizeof(char) * nl);
        if(!str1) {
                fprintf(stdout, "malloc failed \n");
                return NULL;
        }
        for(i = 0; i < l; i++) {
                if(str[i] == ' ') {
                        str1[j++] = '%';
                        str1[j++] = '2';
                        str1[j++] = '0';
                } else {`enter code here`
                        str1[j++] =  str[i];
                }
        }
        str1[j] = '\0';
        return str1;
}