Replace multiple spaces by single space in C

2019-02-19 09:14发布

问题:

I want to repace multiple spaces in a string by single space, however my following code doesn't work. What's the logical mistake?

#include<stdio.h>
#include<string.h>
main()
{
char input[100];
int i,j,n,z=0;
scanf("%d",&n);
z=n;
for(i=0;i<n;i++)
scanf("%c",&input[i]);
for(i=0;i<n;i++)
{
    if(input[i]==' ' && (input[i+1]==' ' || input[i-1]==' '))
    {
        --z;
        for(j=i;j<n;j++)
        input[j]=input[j+1];
    }
}
for(i=0;i<z;i++)
    printf("%c",input[i]);
printf("\n");
}

回答1:

The scanf is giving you some problem: it reads the \n you give after inputting the length n. So, you will miss the last character since for loop exits. The already given answers are good enough. But if you want to follow your own logic, try this:

void main()
{
    char input[100];
    int i = 0,j,n = 0;
    while ((input[n] = getchar()) != '\n') {
        n++;
    }
    input[n] = '\0';
    while (i < n)
    {
        if(input[i]==' ' && (input[i+1]==' ' || input[i-1]==' '))
        {
            for(j=i;j<n;j++)
            input[j]=input[j+1];
            n--;
        }
        else
        {
            i++;
        }
    }
    printf("%s\n",input);
    printf("\n");
}


回答2:

I would do something like this:

void replace_multi_space_with_single_space(char *str)
{
    char *dest = str;  /* Destination to copy to */

    /* While we're not at the end of the string, loop... */
    while (*str != '\0')
    {
        /* Loop while the current character is a space, AND the next
         * character is a space
         */
        while (*str == ' ' && *(str + 1) == ' ')
            str++;  /* Just skip to next character */

       /* Copy from the "source" string to the "destination" string,
        * while advancing to the next character in both
        */
       *dest++ = *str++;
    }

    /* Make sure the string is properly terminated */    
    *dest = '\0';
}

Of course, the above function requires you to properly terminate the string, which you currently do not.

What the function above does, is basically copy the string over itself. The exception is when there is a space, when multiple spaces are simply discarded.

Since the function modifies the source string, it can not be used on string literals.



回答3:

if(input[i]==' ' && (input[i+1]==' ' || input[i-1]==' '))

case " 1 3" : when i == 0 accses input[i-1] Out-of-Bounds

scanf("%d",&n);

remain newline, (input[0] <-- '\n')

fix to

scanf("%d%*c",&n);

#include <stdio.h>

char* uniq_spc(char* str){
    char *from, *to;
    int spc=0;
    to=from=str;
    while(1){
        if(spc && *from == ' ' && to[-1] == ' ')
            ++from;
        else {
            spc = (*from==' ')? 1 : 0;
            *to++ = *from++;
            if(!to[-1])break;
        }
    }
    return str;
}

int main(){
    char input[]= "  abc   de  f  ";

    printf("\"%s\"\n", uniq_spc(input));//output:" abc de f "
    return 0;
}


回答4:

You cant try this simple code:

#include <stdio.h>

#define IN 1
#define OUT 0

int main() {
  int c, spaces, state;

  spaces = 0;
  state = OUT;  
  while ((c = getchar()) != EOF) {

      if ( c == ' ') {
           ++spaces;
           state = OUT;
       }
      else if (state == OUT) {
          state = IN;
          spaces = 0;
      }
      if (c == ' ' && spaces > 1 && state == OUT)
          c = 0;            
      putchar(c);
  }
  return 0;
}


回答5:

You have to fix the following for loop. the limit of your for loop should be z and not n

for(j=i;j<n;j++)
input[j]=input[j+1];

by

for(j=i;j<z;j++)
input[j]=input[j+1];

BTW: the fist charachter get by your scanf() (which read charachters) is newline (\n). this newline come from the first scanf() of decimal(%d)



回答6:

Why make it more complicated than it needs to be? You can use strtok to check for single whitespaces and just ignore those. Then you can use strcat to concatenate the string into a full sentence and then you're done.

This is how I did it:

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

int main(void) {
    char *pch;
    char sentence[1000];
    char without[1000];

    printf("Sentence: ");
    fgets(sentence,1000, stdin);
    strtok(sentence, "\n"); // remove any newlines
    pch = strtok(sentence, " ");
    while(pch != NULL) {
      strcat(without, pch);
      strcat(without, " \0");
      pch = strtok(NULL, " ");
    }
    without[strlen(without)-1] = '\0'; // remove extra whitespace at the end
    printf("|%s|\n",without);
    return 0;
}


回答7:

#include<stdio.h>
#include<string.h>
int main(void)
    {
        char input[1000];
        int i=0;
        gets(input); 
        for(i=0;input[i]!='\0';i++)
        {
            if(input[i]!=' ' || input[i+1]!=' ')
                printf("%c",input[i]);
        }
        return 0;
    }


回答8:

#include <stdio.h>
#include <stdlib.h>
void remove_blanks(char* s);

int main()
{
    char const s[] = {'1',' ',' ','2',' ',' ','3'};
    remove_blanks(s);
    printf("%s",s);
    return 0;
}

void remove_blanks(char* s){
    int i=0, delta=0, cnt=0;

    for (i=0;s[i];++i){
        if (s[i]==' ') cnt++;
        if (cnt>1){
            delta+=1;
            cnt=0;
        }
        s[i-delta]=s[i];
        if(delta>0) s[i]='\0';

    }
}