简体   繁体   English

从字符串中删除多余的空格-C编程

[英]Removing extra whitespaces from a string - C programming

The task is to remove all of the extra whitespaces in a string, for example if a string looks like this: 任务是删除字符串中所有多余的空格,例如,如果字符串看起来像这样:

   volim      OR      

after the program is done it should look like this: 程序完成后,它应如下所示:

volim OR

so the program has to remove all the whitespaces before and after the strings, and those in between the words, so in the end there is just one between each word. 因此程序必须删除字符串前后的所有空格以及单词之间的空格,因此最后每个单词之间只有一个空格。 This what I have so far : 这是我到目前为止所拥有的:

#include <stdio.h>

char *IzbaciViskaRazmake (char *Str)
{
    char *p = Str;
    char *p2 = Str;
    while(*p!='\0')
    {
        if(*p==' ')
            p++;
        else if(*p!=' ')
        {
            *p2 = *p;
            p2++;
            p++;
        }
    }
    *p2='\0';
    return Str;
}

int main() {
    char tekst[] = "        volim      OR      ";
    IzbaciViskaRazmake(tekst);
    printf("'%s'",tekst);
    return 0;
}

The problem with my code is that it removes all of the whitespaces so it gives the output 我的代码的问题是,它删除了所有空格,因此它给出了输出

volimOR

How can I repare my code, so it keeps the whitespaces between the words. 我如何重新编写我的代码,以便在单词之间保留空格。 PS- The use of pointers is a must. PS-必须使用指针。

You can do this by adding the first 您可以通过添加第一个 (whitespace) to *p2 and skipping the rest (空格)到*p2并跳过其余部分 (whitespace) using a while-loop . (空白)使用while-loop

Try this modified code , This will work :- 试试这个修改后的代码,它将起作用:

#include <stdio.h>

char *IzbaciViskaRazmake(char *Str)
{
    char *p = Str;
    char *p2 = Str;
    while (*p != '\0')
    {
        if (*p == ' ')
        {
            if (*p != *Str) // Not begining
            {
                *p2 = *p; // adding the first ' '
                p2++;
                p++;
            }
            while (*p == ' ') // skipping the rest ' '
            {
                p++;
            }
        }
        else
        {
            *p2 = *p;
            p2++;
            p++;
        }
    }
    if (*(p2 - 1) == ' ') //ends with space
    {
        p2--;
    }
    *p2 = '\0';

    return Str;
}

int main()
{
    char tekst[] = "        volim      OR      ";
    IzbaciViskaRazmake(tekst);
    printf("'%s'", tekst);
    return 0;
}

Output :- 输出:-

'volim OR'

Anoopknrs code gave me an idea how this code actually works, so I have managed to quickly fix it. Anoopknrs代码让我知道了该代码实际上是如何工作的,因此我设法迅速对其进行了修复。 Here is the fully working, hopefully it can help some other people. 这是充分发挥作用的方法,希望它可以对其他人有所帮助。

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

    char *IzbaciViskaRazmake (char *Str)
    {
        char *p = Str;
        char *p2 = Str;
        while(*p!='\0')
        {
            if(*p==' ')
                p++;
            else if(*p!=' ')
            {
                *p2 = *p;
                p2++;
                p++;
                if(*p==' ')
                    {
                        *p2=*p;
                        p2++;
                        p++;
                    }
            }
        }
        *(p2-1)='\0';
        return Str;
    }

    int main() {
        char tekst[] = "        volim      OR      ";
        IzbaciViskaRazmake(tekst);
        printf("'%s'",tekst);
        return 0;
    }

I think you should divide this into three separate tasks: 我认为您应该将其分为三个独立的任务:

  • Remove all whitespaces before first non-whitespace character 删除第一个非空白字符之前的所有空白
  • Remove all whitespaces after last non-whitespace character 删除最后一个非空格字符后的所有空格
  • Remove all whitespaces between words 删除单词之间的所有空格

This is three pretty separate tasks, and a reasonable assumption in your case seems to be to only count ' ' as whitespace. 这是三个非常独立的任务,在您的情况下,一个合理的假设似乎只是将' '视为空格。 However, functions like this should i general return a NULL pointer on failure. 但是,这样的函数通常应该在失败时返回NULL指针。

So we can declare this function: 因此,我们可以声明以下函数:

char * trimSpaces(char *str) {
    if(!str) return NULL; // If we get a NULL pointer as input
    if((str = trimInitialSpaces(str)) == NULL) return NULL;
    if((str = trimEndingSpaces(str)) == NULL) return NULL;
    if ((str = trimSuperfluousSpaces(str)) == NULL) return NULL;
    return str;
}

Now you have three functions to write, but each of these is simpler than your original function. 现在您要编写三个函数,但是每个函数都比原始函数要简单。

The implementation of trimIntitialSpaces could then look like this: trimIntitialSpaces的实现如下所示:

char * trimInitialSpaces(char *str) {
    if(!str) return NULL;
    char * ptr = str;
    int len = strlen(str); // Get length of string                              
    if(len == 0) return str; // If len is 0, there's nothing to do
    while(*ptr == ' ' && *ptr != '\0') ptr++; // Find first non-space                               
    // memmove can handle overlapping arrays, which memcpy cannot               
    memmove(str, ptr, len-(ptr-str)+1);
    return str;
}

You have two functions left to write now. 现在还有两个函数需要编写。 trimEndingSpaces(str) is slightly trickier, but all in all almost the same as trimInitialSpaces(str) . trimEndingSpaces(str)有点棘手,但总的来说与trimInitialSpaces(str)几乎相同。 And then you only have trimSuperfluosSpaces(str) left, which is the trickiest one. 然后只剩下trimSuperfluosSpaces(str) ,这是最棘手的一个。 But now you can debug all these three separate. 但是现在您可以调试所有这三个单独的程序。 Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM