【问题标题】:Function to remove spaces from string/char array in C从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*/
    }
}

【问题讨论】:

标签: c arrays string


【解决方案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);
        

        【讨论】:

          猜你喜欢
          • 2019-05-21
          • 2022-11-16
          • 1970-01-01
          • 1970-01-01
          • 2018-04-12
          • 2010-12-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多