web-dev-qa-db-fra.com

Fonction permettant de supprimer des espaces du tableau string/char en C

La question posée ici est très similaire à ce qui me pose un problème. La différence est que je dois passer un argument à une fonction qui supprime les espaces et renvoie le tableau de chaînes/caractères résultant. Le code fonctionne pour supprimer les espaces, mais pour une raison quelconque, il me reste des caractères de fin laissés par le tableau d'origine. J'ai même essayé strncpy mais j'avais beaucoup d'erreurs.

Voici ce que j'ai jusqu'à présent:

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

Après avoir supprimé les espaces blancs de la input, vous n’avez pas terminé avec un zéro-terminator (\0) car la nouvelle longueur est inférieure ou égale à la chaîne originale.

Il suffit de le terminer à la fin de votre boucle:

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;
}
12
P.P.

Vous ne mettez pas fin à la sortie, et comme elle a peut-être diminué, vous y laissez la vieille queue.

De plus, je suggérerais que le traitement de j, qui est toujours incrémenté dans la boucle et doit ensuite être décrémenté manuellement si le caractère actuel n'est pas copié, pour être quelque peu sous-optimal. Ce n'est pas très clair, et c'est un travail inutile (incrémenter j) qui doit même être annulé lorsqu'il n'est pas souhaité. Assez déroutant.

C'est plus facile d'écrire comme:

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

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

  return out;
}
11
unwind

Comme d'autres l'ont mentionné, la même chaîne est utilisée à la fois pour la source et la destination, et une fin de chaîne n'est pas conservée.

Vous pourriez faire de la manière suivante aussi.

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

Vous devez renvoyer la chaîne après avoir ajouté le terminateur null (\ 0) après le bloc de boucle for

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;                                                          
}
0
Sankar Mani

Ce code fonctionne avec la complexité temporelle de 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);
0
razAguls deztiny

Si vous devez filtrer plus d'un caractère à la fois, vous pouvez trouver quelque chose comme:

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

Utile; il vous suffit de fournir une liste de caractères dans le filtre que vous souhaitez supprimer. Par exemple, "\ t\n", pour les onglets, les nouvelles lignes et les espaces.

0
Owl