简体   繁体   English

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

[英]Remove extra whitespace from a string in C

I have this string我有这个字符串

"go    for    goa" 

and the output should be并且输出应该是

"go for goa"

I want to remove the extra spaces.我想删除多余的空格。 That means two or more consecutive spaces should be replaced with one space.这意味着两个或多个连续空格应替换为一个空格。 I want to do it using an in place algorithm.我想使用就地算法来做到这一点。

Below is the code I tried but it doesn't work:以下是我尝试过但不起作用的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Function to remove spaces in an string array */
char *removeSpaces(char *str) {
  int  ip_ind = 1;
  /* In place removal of duplicate spaces*/
  while(*(str + ip_ind)) {
    if ((*(str + ip_ind) == *(str + ip_ind - 1)) && (*(str + ip_ind)==' ')) {
      *(str_ip_ind-1)= *(str + ip_ind);
    }
    ip_ind++;
  }
  /* After above step add end of string*/
  *(str + ip_ind) = '\0';
  return str;
}
/* Driver program to test removeSpaces */
int main() {
  char str[] = "go   for  go";
  printf("%s", removeSpaces(str));
  getchar();
  return 0;
}

Most solutions seem needlessly complicated:大多数解决方案似乎不必要地复杂:

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

void strip_extra_spaces(char* str) {
  int i, x;
  for(i=x=0; str[i]; ++i)
    if(!isspace(str[i]) || (i > 0 && !isspace(str[i-1])))
      str[x++] = str[i];
  str[x] = '\0';
}

int main(int argc, char* argv[]) {
  char str[] = "  If  you  gaze   into  the abyss,    the   abyss gazes also   into you.    ";
  strip_extra_spaces(str);
  printf("%s\n",str);
  return 0;
}

I can't even tell what your function is trying to do.我什至无法判断您的功能正在尝试做什么。 For one thing, the first time through, that -1 will access before the start of the string.一方面,第一次通过,-1 将在字符串开始之前访问。 Try something like:尝试类似:

char *removeSpaces(char *str) {
    char *inp = str, *outp = str;
    int prevSpace = 0;

    while (*inp) {
        if (isspace(*inp)) {
            if (!prevSpace) {
                *outp++ = ' ';
                prevSpace = 1;
            }
        } else {
            *outp++ = *inp;
            prevSpace = 0;
        }
        ++inp;
    }
    *outp = '\0';
    return str;
}

You aren''t checking for a space.. You are checking for a tab.您不是在检查空格.. 您是在检查选项卡。 Replace \\t with (I mean space..)将 \\t 替换为(我的意思是空格..)

Your if condition doesn't work.您的if条件不起作用。 I will show you my code.我会告诉你我的代码。 It is similar to yours, by just using two pointers: back and front .它与您的类似,只需使用两个指针: backfront

If front is not a space, or front is a space but back is not a space, you need to copy front to back+1 .如果front不是空格,或者front是空格而back不是空格,则需要将front复制到back+1

char *removeSpaces(char *str)
{
    if (*str == '\0') return str;

    char *back = str;
    char *front = str + 1;
    /* In place removal of duplicate spaces*/
    while(*front != '\0')
    {
        if (*front != ' ' || *back != ' ')    // highlight
            *(++back) = *front;
        front++;
    }

    /* After above step add end of string*/
    *(back + 1) = '\0';

    return str;
}

Hope this may help you.希望这可以帮助你。

Would tell best answer left space @end ?会告诉最佳答案留下空间@end 吗? Here simple translation to JS:这里简单翻译成JS:

 function strip_extra_spaces(str) { var i, x; for (i = x = 0; str[i]; ++i) if (!isspace(str[i]) || (i > 0 && !isspace(str[i - 1]))) str[x++] = str[i]; str[x] = '\\0'; return str; } str = " If you gaze into the abyss, the abyss gazes also into you. "; console.log( strip_extra_spaces(str.split("")) .join("") .replace(/\\0.+/g, "") .replace(/\\s/g, '☐') ) function isspace(c) { return c == ' '; }

Looking for something similar in C# to compare multiple strings and made this - inspired by recursion.ninja's and similar C# answer to Efficient way to remove ALL whitespace from String?在 C# 中寻找类似的东西来比较多个字符串并做了这个 - 灵感来自 recursion.ninja 和类似的 C# 对Efficient way to remove all whitespace from String 的回答 - also problematic - removed spaces completely. - 也有问题 - 完全删除了空格。

public static string TrimAllWithInplaceCharArray(string a) {
    var len = a.Length;
    var srcA = a.ToCharArray();
    int dstIdxA = 0;
    int planSpace = 0;

    for (int i = 0; i < len; ++i) {
        var ch = srcA[i];
        switch (ch) {
            case '\u0020': case '\u00A0': case '\u1680': case '\u2000': case '\u2001':
            case '\u2002': case '\u2003': case '\u2004': case '\u2005': case '\u2006':
            case '\u2007': case '\u2008': case '\u2009': case '\u200A': case '\u202F':
            case '\u205F': case '\u3000': case '\u2028': case '\u2029': case '\u0009':
            case '\u000A': case '\u000B': case '\u000C': case '\u000D': case '\u0085':
                if (planSpace == 1) planSpace = 2;
                break;

            default:
                if (planSpace > 1)
                {
                    srcA[dstIdxA++] = ' ';
                }
                srcA[dstIdxA++] = ch;
                planSpace = 1;
                break;
        }
    }
    return new string(srcA, 0, dstIdxA);
}

The problem:问题:

  1. You are tracking the '\\t' tab, but you have to remove the spaces.您正在跟踪 '\\t' 选项卡,但您必须删除空格。
  2. Also, you are tracking and finding the '\\t', but you have no steps to removing it (I added one).此外,您正在跟踪并找到“\\t”,但您没有删除它的步骤(我添加了一个)。
  3. Every-time you mustn't increment the ip_ind , you must inc, only when deletion is not done, because when deletion is done, that scenario will be equal to incremented.每次你不能增加ip_ind ,你必须增加,只有当删除没有完成时,因为当删除完成时,那个场景将等于增加。
  4. Your scenario will fail for "" , to avoid it, add a check parameter as below (Method 1) or else start from ip_ind from 0 as in (Method 2).您的场景将因""而失败,为了避免它,添加一个检查参数如下(方法 1),或者从ip_ind开始,从 0 开始(方法 2)。 (Thanks to @Lee Daniel Crocker) (感谢@Lee Daniel Crocker)

Solution:解决方案:

You could try like this.,你可以这样试试

Method 1 : ip_ind starts from one.方法一:ip_ind从1开始。

/* Function to remove spaces in an string array */
char *removeSpaces(char *str)
{
  int  ip_ind = 1;
  char *ptr;

  if(*str)
    return str;

  /* In place removal of duplicate spaces*/
  while(*(str + ip_ind))
  {
    if ( (*(str + ip_ind) == *(str + ip_ind - 1)) && (*(str + ip_ind)==' ') )
    {
        ptr = str + ip_ind;
        //Functionality for removal of spaces.
        do{
           *(ptr-1) = *ptr;
        }while(*ptr++ != '\0');


    }
    else //Inc only if deletion is not done.
    ip_ind++;
  }

 /* After above step add end of string*/
  *(str + ip_ind) = '\0';

 return str;
}

Method 2 : ip_ind starts from zero.方法二:ip_ind 从零开始。

char *removeSpaces(char *str)
{
  int  ip_ind = 0;
  char *ptr;
  /* In place removal of duplicate spaces*/
  while(*(str + ip_ind))
  {
    if ( (*(str + ip_ind) == *(str + ip_ind + 1)) && (*(str + ip_ind)==' ') )
    {
        ptr = str + ip_ind+1;

        do{
           *(ptr-1) = *ptr;
        }while(*ptr++ != '\0');


    }
    else
    ip_ind++;
  }

 /* After above step add end of string*/
  *(str + ip_ind) = '\0';

 return str;
}

There you go:你去吧:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Function to remove spaces in an string array */
char *removeSpaces(char *str) {
  int  ip_ind = 0;
  while (*(str+ip_ind) != 0) {
    if (*(str + ip_ind++) == 32) {
      if (*(str + ip_ind) == 32) {
        int x=ip_ind;
        while (*(str + x +1) != 0) {
          *(str + x)= *(str + 1 + x++);
        }
        *(str + x)= 0;
        --ip_ind;
      }
    }
  }
  return str;
}
/* Driver program to test removeSpaces */
int main() {
  char str[] = "go   for  go";
  printf("%s\n", str);
  printf("%s\n", removeSpaces(str));
  char str2[] = "go     for  go for go";
  printf("%s\n", str2);
  printf("%s\n", removeSpaces(str2));
  return 0;
}

Output:输出:

dda$ ./a.out
go   for  go
go for go
go     for  go for go
go for go for go
dda$

Simple one for You简单给你

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char a[100];
int i,t,k;
scanf("%[^\n]s",a);
t=strlen(a);
for(i=0;i<t;)
{
    if((a[i]==' ')&&(a[i+1]==' '))
    {
        for(k=i+1;k<t;k++)
        {
            a[k]=a[k+1];
        }
        t=t-1;
    }
    else
        i++;
}
printf("%s",a);
return 0;
}

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

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