在不使用任何预定义函数的情况下,在 C 中删除字符串中的多余空间

问题描述 投票:0回答:3

我想在不使用任何预定义函数的情况下删除 C 中字符串中的多余空格。
这是我的代码:
但仍然在 XYZ 之后打印一个额外的空间。
有没有更好的方法请分享

#include <stdio.h>
#include <string.h>

int main() {
    char str[30] = "   abcdef   abc   xyz   ";
    int l = strlen(str),n=0;
    printf("(");                // added for clarity
    for(int i=0;i<l;i++)
    {
        if(str[i]==' ')
        {
            n++;
            if(i==0 || i==l-1)
            {
                continue;
            }
            else
            {
                if(n>1)
                {
                    continue;
                }
                else{
                    printf("%c",str[i]);
                }
            }
        }
        else{
            n=0;
            printf("%c",str[i]);
        }
    }
    printf(")\n");             // added for clarity
    return 0;
}

程序输出为

(abcdef abc xyz )

预期产出是

(abcdef abc xyz)
c char whitespace c-strings trim
3个回答
3
投票

每次当

n
等于
1
i
不等于
0
l-1
时,你的程序总是输出一个空格。因此将始终输出一个尾随空格(如果至少有两个尾随空格)。

还有许多 continue 语句使您的代码过于复杂。

并且使用标准字符串函数

strlen
是多余的。

始终尝试编写更通用的代码。那就是你可以编写一个单独的函数,可以调用任何字符串来输出它。

这里有一个演示程序。

#include <stdio.h>

void output_string( const char *s )
{
    int space = 0;

    for ( ; *s != '\0'; ++s )
    {
        if (*s != ' ')
        {
            if (space) putchar( ' ' );

            putchar( *s );

            space = s[1] == ' ';
        }
    }
}

int main( void )
{
    putchar( '(' );
    output_string( "   abcdef   abc   xyz   " );
    printf( ")\n" );
}

程序输出为

(abcdef abc xyz)

如果包含制表符的处理功能会更通用

'\t'
.

为此,包含标题

<ctype.h>
并更改此语句就足够了

space = s[1] == ' ';

space = isblank( ( unsigned char )s[1] );

如您所见,该函数没有 continue 语句。如果可能,您应该避免使用 continue 语句。通常使用 continue 语句会使程序的可读性降低。


2
投票

你的代码的目标是做两件事。

  1. 如果单词之间有多个空格,则只打印一个空格。
  2. 如果开头或结尾有空格,请删除所有这些空格。

你的程序逻辑处理 1) 很好。它还可以在开始时提供空格。但是,它不处理末尾的空格。这是因为您不知道空格序列的开头是否是结尾序列,所以您在知道它是结尾序列之前就打印了空格。

解决这个问题的最好方法是“预处理”,即查看循环之前的字符串并找到第一个非空格字符。并查看字符串并找到最后一个非空格字符(从末尾开始向后移动。)

现在您可以使用您展示的算法处理从起始位置到结束位置的字符,它会起作用。

帽子提示:@weather vane 的评论,说的是同样的事情,但没有像这个答案那样解释。


1
投票
  1. 使用功能。
  2. 无需打电话
    strlen
  3. l
    的类型错误(应该是
    size_t
char *trimAndStrip(char *str, char ch)
{
    char *head = str, *tail = str;
    if(str)
    {
        while(*tail == ch) tail++;
        while(*tail)
        {
            if(*tail != ch) *head++ = *tail++;
            else 
            {
                *head++ = *tail++;
                 while(*tail == ch) tail++;
            }
        }
    
        if(head > str && *head == ch) head--;
        *head = 0;
    }
    return str;
}

int main(void)
{
    char str[] = "   abcdef   abc   xyz   ";
    char str1[] = "abcdefxyz";
    char str2[] = "       ";
    char str3[] = "";

    printf("\"%s\"\n", trimAndStrip(str, ' '));
    printf("\"%s\"\n", trimAndStrip(str1, ' '));
    printf("\"%s\"\n", trimAndStrip(str2, ' '));
    printf("\"%s\"\n", trimAndStrip(str3, ' '));
}
© www.soinside.com 2019 - 2024. All rights reserved.