【问题标题】:Function removes extra spaces but leaves one space between words in a char pointer函数删除多余的空格,但在 char 指针中的单词之间留下一个空格
【发布时间】:2013-04-29 20:13:23
【问题描述】:

我需要一个函数,该函数将采用 char *s = "abc def gf ijklmn" 之类的 char 指针。如果它通过函数 int space_remove(char *) 传递,它应该返回额外空格的数量并修改字符串并取出额外的空格。

int space_remove(char *s)
{
    int i = 0, ic = 1, r = 0,space = 0;
    //char *sp = (char *) malloc(strlen(s) * sizeof(char));
    char sp[256];
    while (*(s+i) != '\0'){
        if (*(s+i) == ' ' && *(s+i+1) == ' '){
            space = 1;
            r++;
        }
        if (space){
            sp[i] = *(s+i+r);
            i++;
        }

        else if (!space){
            sp[i] = *(s+i+r);
            i++;

        }
        else {
            sp[i] = *(s+i+r);
            i++;
        }
    }
    sp[i+1] = '\0';
    printf("sp:%s \n",sp);
    s = sp;
    //free(sp);
    return r;
}

这里有什么帮助吗?

如果字符串是“abc(10 个空格)def(20 个空格)hijk”,它应该返回“abc(1 个空格)def(1 个空格)hijk”

【问题讨论】:

  • OT:一如既往i i+r所有sp都可以替换为s。这允许解析超过 255 个字符的字符串。
  • OT^2:代表可读性只需决定是使用*(s+x) 还是s[x] 表示法来添加数组元素。这取决于你,但不要将两者混用。

标签: c function space


【解决方案1】:

有两个问题

  1. while 循环中将space 重置为0

  2. 不要返回sp,因为它是本地字符数组。您可以改为在s 中复制字符串。

    strcpy(s, sp);

而不是

s = sp;

strcpy 是安全的,因为sp 的长度应该是s 的最大长度,当没有要修剪的东西时。

【讨论】:

  • 我将空间重置为 0 并且我做了 strcpy 但它并没有带走额外的空间
  • @KeyMaker,我认为你需要重新审视你的逻辑。您的代码将空格减半。一般来说,逻辑是如果找到空间,跳过更多的空间(不要放在sp中。
【解决方案2】:

这是工作代码:

    #include<stdio.h>
int space_remove(char *s)
{
    char *s1=s;
    int count=0;
    while(*s){
        *s1++=*s++; // copy first even if space, since we need the 1st space
        if(*(s-1) == ' '){ //if what we just copied is a space
            while(*s ==' '){
                count++;
                s++; // ignore the additional spaces
            }
        }
    }
    *s1='\0'; //terminate
    return count;
}

void main(int argc, char *argv[]){
    //char *str="hi     how r     u";
    int count=space_remove(argv[1]);
    printf("%d %s",count,argv[1]);
}

修改后的答案:

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int space_remove(char *s)
{
    char *s1=malloc(strlen(s)*sizeof(char));
    char *s2=s1; // for printing
    int count=0;
    while(*s){
        *s1++=*s++; // copy first even if space, since we need the 1st space
        if(*(s-1) == ' '){ //if what we just copied is a space
            while(*s ==' '){
                count++;
                s++; // ignore the additional spaces
            }
        }
    }
    *s1='\0'; //terminate
    printf("%s",s2);
    return count;
}

void main(int argc, char *argv[]){
    char *str="hi     how r     u";
    int count=space_remove(str);
    printf("\n%d",count);
}

【讨论】:

  • 你应该把 s1++ 和 s++ 放在 if 语句之后,这样代码更容易阅读。
  • 我试过了,它没有用,我想返回多少额外的空格,它在这一行出现了段错误 - *s1++=*s++;
  • 它在我的电脑上工作得很好(我试过两个,一个mac和一个windows)。我已经添加了整个代码。它给出分段错误的输入是什么?你用的是什么编译器?
  • 我正在使用 gccx 在 linux 机器上编译,我只使用了 gcc,但它仍然给我一个 seg 错误。
  • 我发现了问题。如果您使用新编辑进行编译,它可以在 linux 机器上运行。使用./a.out "adasd asdas " 运行问题是,当您将字符串分配给char * 时,它会将其转换为const char *。我正在尝试找出解决方法。