【问题标题】:Remove spaces from string doesn't return anything从字符串中删除空格不会返回任何内容
【发布时间】:2018-09-07 08:33:52
【问题描述】:

此代码从字符串中删除空格。

char *RemoveSpaces(char *source)
{  
    char* i = source;
    char* j = source;
    while(*j != '\0')
    {
        *i = *j++;
        if(*i != ' ')
            i++;
    }
    *i = 0;
    return i;
}

但是当我使用printf 时,它不会返回任何内容。

printf("%s", RemoveSpaces("HELLO WORLD!!! COME ONE\r"));

【问题讨论】:

  • 您可能还对this SO article感兴趣
  • 您永远不会删除任何空格。检查它是否是您复制的之前而不是之后的空格。
  • @Lundin 当 char 为空格时,它通过 not 递增 i 来删除空格。逻辑有点倒退,但确实有效。
  • @4386427 是的,但它不必要地低效。先复制后验证通常是一个很大的禁忌。

标签: c


【解决方案1】:
*i = 0;
return i;   // wrong pointer returned

错了。它返回一个指向字符串终止的指针(即指向 0 的指针)。因此它什么也不打印。

试试:

*i = 0;            // or *i = '\0';
return source;     // correct pointer returned

此外,不允许修改字符串文字。而是这样做:

char str[] = "HELLO WORLD!!! COME ONE\r";
printf("%s", RemoveSpaces(str));

【讨论】:

  • 在我的代码中,我使用 char 和指针。所以我不能为此使用 char 数组
  • @Dim 是的,您可以...当您将数组传递给函数时,它会衰减为指针。
  • 我不明白为什么我不能在我的方法中传递 *pointer 并且我需要使用 char 数组。
  • @Dim 正如我上面写的:代码传递了一个指针,因为数组衰减为一个指针。如果您愿意,您可以改为:char str[] = "HELLO WORLD!!! COME ONE\r"; char *pointer_to_string = str; printf("%s", RemoveSpaces(pointer_to_string)); 它会给出相同的结果
【解决方案2】:

对您的空间删除逻辑稍作调整可能会让事情变得更有意义。而不是设置

    *i = *j++;
    if(*i != ' ')
        i++;

在您测试是否*i != ' ' 之前,您可能会发现先测试然后分配更有意义(其中p 是您的iep(结束指针)是您的j),例如

    while (*ep) {           /* iterate ep from beginning to end of src */
        if (*ep != ' ')     /* if its not a space */
            *p++ = *ep;     /* set begin pointer to char at end ptr, advance */
        ep++;               /* advance to next char */
    }
    *p = 0;                 /* nul-terminate src at p */

从这个意义上说,如果当前字符不是空格,您只分配和推进初始指针。

在您的示例和此处,您正在修改source 的内容,您的'i''j' 指针用于迭代source 中的字符,因此当您完成迭代时,你 return source (或者源可以在调用者中使用而无需返回,因为你正在就地修改 source 的内容。

将这些部分放在一起,您可以执行类似以下的操作,将字符串作为代码的第一个参数删除空格(如果没有给出参数,则默认使用"HELLO WORLD!!! COME ONE\n"),例如

#include <stdio.h>

char *rmspaces (char *src)
{
    char *p = src,          /* pointer to beginning of src */
        *ep = src;          /* pointer to iterate to the end of src */

    while (*ep) {           /* iterate ep from beginning to end of src */
        if (*ep != ' ')     /* if its not a space */
            *p++ = *ep;     /* set begin pointer to char at end ptr, advance */
        ep++;               /* advance to next char */
    }
    *p = 0;                 /* nul-terminate src at p */

    return src;
}

int main (int argc, char **argv) {

    char *s = argc > 1 ? argv[1] : (char[]){"HELLO WORLD!!! COME ONE\n"};
    printf ("%s", rmspaces (s));

    return 0;
}

(注意:,您的就地编辑很好,但在我的情况下,source(或src)必须是可修改的,这意味着您不能通过 string-literal as source(这可能是 SegFault)。在默认情况下使用 compound-literal 以确保过去的测试是可修改的字符数组)

使用/输出示例

$ ./bin/rmspaces
HELLOWORLD!!!COMEONE

检查一下,如果您还有其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    • 2012-03-08
    • 2011-09-21
    • 2017-11-20
    相关资源
    最近更新 更多