从C中的字符串/字符数组中删除空格的函数

Posted

技术标签:

【中文标题】从C中的字符串/字符数组中删除空格的函数【英文标题】:Function to remove spaces from string/char array in C 【发布时间】:2012-10-26 09:25:33 【问题描述】:

here 提出的问题与我遇到的问题非常相似。不同之处在于我必须将参数传递给删除空格并返回结果字符串/字符数组的函数。我得到了删除空格的代码,但由于某种原因,我留下了原始数组中遗留的尾随字符。我什至尝试了 strncpy,但我遇到了很多错误。

这是我目前所拥有的:

#include <stdio.h>
#include <string.h>
#define STRINGMAX 1000                                                      /*Maximium input size is 1000 characters*/

char* deblank(char* input)                                                  /* deblank accepts a char[] argument and returns a char[] */

    char *output=input;
    for (int i = 0, j = 0; i<strlen(input); i++,j++)                        /* Evaluate each character in the input */
    
        if (input[i]!=' ')                                                  /* If the character is not a space */
            output[j]=input[i];                                             /* Copy that character to the output char[] */
        else
            j--;                                                            /* If it is a space then do not increment the output index (j), the next non-space will be entered at the current index */
    
    return output;                                                          /* Return output char[]. Should have no spaces*/

int main(void) 
    char input[STRINGMAX];
    char terminate[] = "END\n";                                             /* Sentinal value to exit program */

    printf("STRING DE-BLANKER\n");
    printf("Please enter a string up to 1000 characters.\n> ");
    fgets(input, STRINGMAX, stdin);                                         /* Read up to 1000 characters from stdin */

    while (strcmp(input, terminate) != 0)                                   /* Check for que to exit! */
    
        input[strlen(input) - 1] = '\0';
        printf("You typed: \"%s\"\n",input);                                /* Prints the original input */
        printf("Your new string is: %s\n", deblank(input));                 /* Prints the output from deblank(input) should have no spaces... DE-BLANKED!!! */

        printf("Please enter a string up to 1000 characters.\n> ");
        fgets(input, STRINGMAX, stdin);                                     /* Read up to another 1000 characters from stdin... will continue until 'END' is entered*/
    

【问题讨论】:

How to remove all spaces and tabs from a given string in C language?的可能重复 【参考方案1】:

input 中删除空格后,您还没有使用 nul-terminator (\0) 终止它,因为新长度小于或等于原始字符串。

只需在你的 for 循环的末尾用 nul 终止它:

char* deblank(char* input)                                         

    int i,j;
    char *output=input;
    for (i = 0, j = 0; i<strlen(input); i++,j++)          
    
        if (input[i]!=' ')                           
            output[j]=input[i];                     
        else
            j--;                                     
    
    output[j]=0;
    return output;

【讨论】:

对我来说效果很好!谢谢。必须将 j 声明移出 for 循环,以便为其提供函数范围可见性。 可能需要考虑删除基于this 的所有空格。【参考方案2】:

你没有终止输出,因为它可能已经缩小了,你把旧的尾巴留在了那里。

另外,我建议处理j,它总是在循环中递增,然后如果当前字符没有被复制,则必须手动递减,这在某种程度上是次优的。这不是很清楚,而且它正在做毫无意义的工作(递增j),甚至在不需要时必须撤消。相当混乱。

更容易写成:

char * deblank(char *str)

  char *out = str, *put = str;

  for(; *str != '\0'; ++str)
  
    if(*str != ' ')
      *put++ = *str;
  
  *put = '\0';

  return out;

【讨论】:

我会更喜欢你的回答,但我对指针的理解只有婴儿。我正在为我的班级阅读的这本书对于像我这样的绝对初学者来说并没有很好地解释事情,老实说,我无法向我的导师解释发生了什么。如果我盯着你的代码足够长的时间,我可以把你所做的事情拼凑起来,但我真的对你的代码如何工作没有一个基本概念。例如,递增“++”如何处理 char 数组?我认为这只能用于数字数据类型。不过还是感谢您的意见! @JohnR This 解决方案应该是公认的解决方案。我希望您现在对 C 指针感到满意,并理解为什么。 @unwind(只是一个小问题)你会自发地想到一个比deblank更好的名字吗?【参考方案3】:

正如其他人提到的,相同的字符串用于源和目标,并且不保留字符串的结尾。

您也可以通过以下方式进行操作。

char* deblank(char* input)                                                  /* deblank accepts a char[] argument and returns a char[] */

    char *output;
    output = malloc(strlen(input)+1);

     int i=0, j=0;
    for (i = 0, j = 0; i<strlen(input); i++,j++)                        /* Evaluate each character in the input */
    
        if (input[i]!=' ')                                                  /* If the character is not a space */
            output[j]=input[i];                                             /* Copy that character to the output char[] */
        else
            j--;                                                            /* If it is a space then do not increment the output index (j), the next non-space will be entered at the current index */
    

    output[j] ='\0';
    return output;                                                          /* Return output char[]. Should have no spaces*/

【讨论】:

【参考方案4】:

在for循环块后添加null(\0)终止符后必须返回字符串

char* deblank(char* input)                                                  

char *output=input;
for (int i = 0, j = 0; i<strlen(input); i++,j++)                        

    if (input[i]!=' ')                                                  
        output[j]=input[i];                                             
    else`enter code here`
        j--;                                                            

output[j]='\0';
return output;                                                          

【讨论】:

【参考方案5】:

如果您需要一次过滤多个字符,您可能会发现如下内容:

char *FilterChars(char *String,char *Filter)
  int a=0,i=0;
  char *Filtered=(char *)malloc(strlen(String)*sizeof(char));
  for(a=0;String[a];a++)
    if(!strchr(Filter,String[a]))
      Filtered[i++]=String[a];
  Filtered[i]=0;
  return Filtered;

有用的;只需在 *Filter 中提供您希望删除的字符列表。例如“\t\n”,用于制表符、换行符和空格。

【讨论】:

【参考方案6】:

此代码的时间复杂度为 O(n)。

char str[]="my name    is Om";
int c=0,j=0;
while(str[c]!='\0')
    if(str[c]!=' ')
        str[j++]=str[c];
    
    c++;

str[j]='\0';
printf("%s",str);

【讨论】:

以上是关于从C中的字符串/字符数组中删除空格的函数的主要内容,如果未能解决你的问题,请参考以下文章

c语言 讲一个字符串str以空格为分割,分割后输出到一个一维数组

从字符数组java中“删除”重复空格

无法从字符串数组中删除空格

C语言程序设计删除空格

根据字符的字符从句子数组中删除重复句子的最佳方法,空格无关紧要

如何用函数删除一个字符串里面的重复的字符,只保留一个?