Quel est le moyen le plus simple et le plus efficace de supprimer des espaces dans une chaîne en C?
Le plus simple et le plus efficace ne vont généralement pas ensemble ...
Voici une solution possible (non testée):
void RemoveSpaces(char* source)
{
char* i = source;
char* j = source;
while(*j != 0)
{
*i = *j++;
if(*i != ' ')
i++;
}
*i = 0;
}
Voici une version très compacte, mais tout à fait correcte:
do while(isspace(*s)) s++; while(*d++ = *s++);
Et voici, juste pour mon amusement, des versions codées en golf qui ne sont pas tout à fait correctes et qui dérangent les commentateurs.
Si vous pouvez risquer un comportement indéfini et ne jamais avoir de chaîne vide, vous pouvez vous débarrasser du corps:
while(*(d+=!isspace(*s++)) = *s);
Heck, si par espace vous entendez simplement le caractère d'espace:
while(*(d+=*s++!=' ')=*s);
N'utilisez pas ça en production :)
Comme nous pouvons le constater à partir des réponses, ceci n’est pas une tâche anodine. Face à une telle tâche, il semblerait que de nombreux programmeurs choisissent de jeter le bon sens par la fenêtre, afin de produire l'extrait le plus obscur qu'ils puissent éventuellement trouver.
Choses à considérer:
' '
.Ce que je ferais:
void remove_spaces (char* restrict str_trimmed, const char* restrict str_untrimmed)
{
while (*str_untrimmed != '\0')
{
if(!isspace(*str_untrimmed))
{
*str_trimmed = *str_untrimmed;
str_trimmed++;
}
str_untrimmed++;
}
*str_trimmed = '\0';
}
Dans ce code, la chaîne source "str_untrimmed" est laissée intacte, ce qui est garanti par l'utilisation de const correcte. Il ne se bloque pas si la chaîne source ne contient rien d'autre qu'une fin nulle. Il termine toujours null par la chaîne de destination.
L'attribution de mémoire est laissée à l'appelant. L'algorithme doit uniquement se concentrer sur le travail prévu. Il supprime tous les espaces blancs.
Il n'y a pas d'astuces subtiles dans le code. Il n'essaie pas de regrouper autant d'opérateurs que possible sur une seule ligne. Cela fera un très pauvre candidat pour le IOCCC . Cependant, il produira à peu près le même code machine que les versions plus obscures à une ligne.
Lorsque vous copiez quelque chose, vous pouvez toutefois optimiser un bit en déclarant les deux pointeurs comme étant restrict
, ce qui est un contrat entre le programmeur et le compilateur, le programmeur garantissant que la destination et la source ne sont pas la même adresse (ou plutôt que les données qu’ils point à ne sont accessibles que par ce pointeur même et non par un autre pointeur). Cela permet une optimisation plus efficace, car le compilateur peut alors copier directement de la source à la destination sans mémoire temporaire.
En C, vous pouvez remplacer certaines chaînes sur place, par exemple une chaîne renvoyée par strdup ():
char *str = strdup(" a b c ");
char *write = str, *read = str;
do {
if (*read != ' ')
*write++ = *read;
} while (*read++);
printf("%s\n", str);
Les autres chaînes sont en lecture seule, par exemple celles déclarées dans le code. Vous devrez les copier dans une zone de mémoire nouvellement allouée et remplir la copie en sautant les espaces:
char *oldstr = " a b c ";
char *newstr = malloc(strlen(oldstr)+1);
char *np = newstr, *op = oldstr;
do {
if (*op != ' ')
*np++ = *op;
} while (*op++);
printf("%s\n", newstr);
Vous pouvez voir pourquoi les gens ont inventé d'autres langues;)
si vous êtes toujours intéressé, cette fonction supprime les espaces du début de la chaîne et je viens juste de le voir fonctionner dans mon code:
void removeSpaces(char *str1)
{
char *str2;
str2=str1;
while (*str2==' ') str2++;
if (str2!=str1) memmove(str1,str2,strlen(str2)+1);
}
#include <ctype>
char * remove_spaces(char * source, char * target)
{
while(*source++ && *target)
{
if (!isspace(*source))
*target++ = *source;
}
return target;
}
Remarques;
#include<stdio.h>
#include<string.h>
main()
{
int i=0,n;
int j=0;
char str[]=" Nar ayan singh ";
char *ptr,*ptr1;
printf("sizeof str:%ld\n",strlen(str));
while(str[i]==' ')
{
memcpy (str,str+1,strlen(str)+1);
}
printf("sizeof str:%ld\n",strlen(str));
n=strlen(str);
while(str[n]==' ' || str[n]=='\0')
n--;
str[n+1]='\0';
printf("str:%s ",str);
printf("sizeof str:%ld\n",strlen(str));
}
C'est le plus simple auquel je puisse penser (TESTED) et ça marche !!
char message[50];
fgets(message, 50, stdin);
for( i = 0, j = 0; i < strlen(message); i++){
message[i-j] = message[i];
if(message[i] == ' ')
j++;
}
message[i] = '\0';
Solution efficace et assez facile:
//Removespaces.
void be_gone_spaces(char *str)
{
char *p = str;
do *(*p == ' ' ? str : str++) = *p;
while (*p++);
}
Je suppose que la chaîne C est dans une mémoire fixe, donc si vous remplacez des espaces, vous devez décaler tous les caractères.
Le plus simple semble être de créer une nouvelle chaîne, de parcourir la chaîne d'origine et de ne copier que des caractères sans espace.