首页 > 解决方案 > 消除字符串中所有多余的空格

问题描述

函数必须消除单词和标点符号之间的所有多余空格,但标点符号和它们之前的单词之间不能有任何空格。

例如我有这个字符串:

Hey   ,how   are you today    ?

我应该得到这个:

Hey, how are you today?

此功能消除了此处的多余空格。但我不知道如何包含标点符号

顺便说一句,我在主函数中调用这个函数

void space_rule(char *str[]){
printf("Enter a string: ");
gets(*str);
puts(*str);

char *p = strtok(*str, " ");
    while(*p!=NULL){
    printf("%s ",p);
    p=strtok(NULL, " ");
}

}

标签: c

解决方案


考虑:

#include <stdio.h>
#include <ctype.h>

int main()
{
    const char* input = "Hey   ,how   are you today    ?" ;
    const char* chp = input ;
    
    // While not end of input...
    while( *chp != '\0' )
    {
        
        // Print all regular characters (not space or punctuation)
        if( !(isspace( *chp ) || ispunct( *chp )) )
        {
            putchar( *chp ) ;
            chp++ ;
        }
        // Print all punctuation followed by a space (except at end)
        else if( ispunct( *chp ) )
        {
            putchar( *chp ) ;
            chp++ ;
            if( *chp != '\0' && !isspace( *chp ) )
            {
                putchar( ' ' ) ;
            }
        }
        // Is space...
        else if( isspace( *chp ) )
        {
            // Skip all space
            while( *chp != '\0' && isspace( *chp ) )
            {
                chp++ ;
            }
            
            // If not end, and not punctuation...
            if( *chp != '\0' && !ispunct( *chp ) )
            {
                // ...insert single space 
                putchar( ' ' ) ;
            }
        }
    }
    
    return 0;
}

但是,您可能需要更仔细地完善您的规则。也许不是所有的标点符号都应该被同等对待?例如:

const char* input = "She said \"Hello\"" ;

输出是:

She said" Hello"  

这不太可能是有意的。为此,您不仅需要包含 的例外规则'"',还需要考虑开始和结束引号并相应地应用规则。给读者的练习——如果你仍然坚持这个问题,我建议你发布一个新问题。

如果你有一个字符串,它会变得非常复杂,例如:

She said, "Hey, how are, you today?"

因为那时你有?"在一起,因为?你想要一个规则:“标点符号后的空格,除非下一个字符也是标点符号”。但是如果?and"被空格隔开,你必须在做出决定之前先消除它。老实说,我放弃了试图找出所有排列。我建议,如果您想这样做,您可以一次应用一个规则多次执行转换,例如:

  1. 将所有多个空格减少到 1 个空格
  2. 如果没有空格,则在标点符号后插入空格,并且它不是一个开头('")。
  3. 删除标点之间的空格
  4. 如果不存在空格,则在打开引号之前插入空格。

通过拥有更简单的规则(在单独的函数中执行)和多次传递,以牺牲效率为代价更容易做到正确。您还可以轻松地重新排序规则的应用以获得预期的结果。例如这里的规则 4 必须在规则 3之后应用。


推荐阅读