简体   繁体   English

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

[英]Function to remove spaces from string/char array in C

The question asked here is very similar to what I am having a problem with. 问的问题在这里是非常相似,我有一个问题。 The difference is that I must pass an argument to a function that removes the spaces and returns the resulting string/char array. 区别在于我必须将一个参数传递给一个删除空格并返回结果字符串/ char数组的函数。 I got the code working to remove the spaces but for some reason I am left with trailing characters left over from the original array. 我得到了代码工作来删除空格但由于某种原因我留下了原始数组遗留的尾随字符。 I even tried strncpy but I was having lots of errors. 我甚至尝试过strncpy,但我遇到了很多错误。

Here is what I have so far: 这是我到目前为止:

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

After removing the white spaces from the input you have not terminated it with nul-terminator ( \\0 ) because the new length is less than or equal to the original string. input删除空格后,您没有使用nul-terminator( \\0 )终止它,因为新长度小于或等于原始字符串。

Just nul-terminate it at the of end your for loop: 只需在你的for循环结束时终止它:

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

You're not terminating the output, and since it might have shrunk, you're leaving the old tail in there. 你没有终止输出,因为它可能会缩小,你就会把旧尾巴留在那里。

Also, I would suggest that the treatment of j , which is always incremented in the loop and then has to be manually decremented if the current character is not copied, to be somewhat sub-optimal. 另外,我建议j的处理总是在循环中递增,然后如果不复制当前字符则必须手动递减,这在某种程度上是次优的。 It's not very clear, and it's doing pointless work (incrementing j ) which even has to be undone when it's not desired. 它不是很清楚,它正在做无意义的工作(递增j ),甚至在不需要的时候也必须撤消。 Quite confusing. 相当混乱。

It's easier written as: 它写得更容易:

char * deblank(char *str)
{
  char *out = str, *put = str;

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

  return out;
}

As others mentioned, same string is used for both source and destination, and a end of string is not maintained. 正如其他人所提到的,源和目标都使用相同的字符串,并且不维护字符串的结尾。

You could do in the following way also. 你也可以用以下方式做。

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

You have to return the string after adding the null(\\0) terminator after the for loop block 在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;                                                          
}

If you need to filter more than one character at a time, you might find something like: 如果您需要一次过滤多个字符,可能会发现如下内容:

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

Useful; 有用; just provide a list of characters in *Filter you wish to strip out. 只需在*滤镜中提供要删除的字符列表。 For example "\\t\\n ", for tabs, newlines and spaces. 例如“\\ t \\ n”,用于制表符,换行符和空格。

This code works with time complexity of O(n). 此代码适用于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);

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

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