【问题标题】:Remove extra whitespace from a string in C从 C 中的字符串中删除多余的空格
【发布时间】:2013-07-20 03:53:58
【问题描述】:

我有这个字符串

"go    for    goa" 

输出应该是

"go for goa"

我想删除多余的空格。这意味着两个或多个连续的空格应该替换为一个空格。我想使用就地算法来做到这一点。

以下是我尝试过的代码,但它不起作用:

#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;
}

【问题讨论】:

    标签: c algorithm whitespace


    【解决方案1】:

    会告诉最佳答案留下空格@end 吗?这里简单翻译成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 == ' ';
    }

    在 C# 中寻找类似的东西来比较多个字符串并做到这一点 - 受到 recursion.ninja 和类似 C# 对Efficient way to remove ALL whitespace from String? 的回答的启发 - 也有问题 - 完全删除了空格。

    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);
    }
    

    【讨论】:

      【解决方案2】:

      大多数解决方案似乎不必要地复杂:

      #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;
      }
      

      【讨论】:

      • @GiorgiMoniava,我修好了
      • 很好的解决方案。
      • 旧,但仍然很棒!谢谢。
      【解决方案3】:

      简单的为您服务

      #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;
      }
      

      【讨论】:

        【解决方案4】:

        问题:

        1. 您正在跟踪“\t”标签,但您必须删除 空格。
        2. 此外,您正在跟踪并找到“\t”,但您没有删除它的步骤(我添加了一个)。
        3. 每次你不能增加ip_ind,你必须增加,只有在没有删除的时候,因为当删除完成时,那个 场景将等于递增。
        4. "" 的场景将失败,为避免这种情况,请添加如下检查参数(方法 1),或者从 ip_ind 从 0 开始(方法 2)。 (感谢@Lee Daniel Crocker)

        解决方案:

        你可以这样试试,

        方法一:ip_ind 从一开始。

        /* 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;
        }
        

        方法二: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;
        }
        

        【讨论】:

        • 不使用那个额外的指针ptr就不能解决这个问题吗?
        • @krrishna 不,这不是因为,您需要ip_ind. 指向当前位置,要遍历到最后,您至少需要一个变量。在这种情况下,它是ptr
        【解决方案5】:

        你去吧:

        #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;
        }
        

        输出:

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

        【讨论】:

          【解决方案6】:

          您的if 条件无效。我会告诉你我的代码。它与您的相似,仅使用两个指针:backfront

          如果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;
          }
          

          希望对您有所帮助。

          【讨论】:

            【解决方案7】:

            您不是在检查空格。您是在检查制表符。将 \t 替换为(我的意思是空格..)

            【讨论】:

              【解决方案8】:

              我什至不知道你的函数试图做什么。一方面,第一次通过时,-1 将在字符串开始之前访问。尝试类似:

              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;
              }
              

              【讨论】:

              • 不,它不会,因为他将 ip_ind 初始化为 1。
              猜你喜欢
              • 1970-01-01
              • 2011-08-05
              • 1970-01-01
              • 2013-06-03
              • 1970-01-01
              • 2022-10-07
              相关资源
              最近更新 更多