Eliminer les espaces superflus

Présentation
Cette fonction supprime les espaces superflus dans une chaîne de caractères.
Téléchargement
Compatibilité
Linux Mac Windows
0  0 
Téléchargé 38 fois Voir les 8 commentaires
Détails
Avatar de fearyourself
Expert éminent sénior
Voir tous les téléchargements de l'auteur
Licence : Autre
Date de mise en ligne : 1er décembre 2010




Avatar de cyberboss cyberboss - Membre à l'essai https://www.developpez.com
le 10/01/2011 à 18:21
Bonjour,

Je la trouve bien mais peut etre un peu longue ??
Pourquoi pas :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
 
char    *epur(char *str) 
{ 
  char  *res = NULL; 
  int   i; 
  int   y; 
 
  y = 0; 
  res = malloc((strlen(str) + 1) * sizeof(char)); 
  /* malloc de la taille initiale + 1 pour le '\0' */ 
  if (res == NULL) 
    return (NULL); 
  for (i = 0; str[i] == ' ' && str[i]; i++); 
  /* saut des espaces au debut */ 
  for (; str[i]; i++) 
    { 
   /* Si c'est un mot on l'ajoute dans notre nouvelle chaine */ 
      if (str[i] != ' ') 
        { 
          res[y] = str[i]; 
          y++; 
        } 
      else if (str[i] == ' ' && str[i + 1] != ' ' && str[i]) 
      /* Sinon, si c'est un espace et que le prochain caractere n'est pas un espace (donc un mot) on ajoute un espace pour separer les mots (verification si on est pas en fin de chaine avec str[i]) */ 
        { 
          res[y] = ' '; 
          y++; 
        } 
    } 
  res[y] = 0; /* Ajout du '\0' de fin de chaine */ 
  res = realloc(res, y); /* realloc de la taille reelle */ 
  return (res); 
}
Qu'en pensez vous ?
Avatar de diogene diogene - Expert éminent sénior https://www.developpez.com
le 10/01/2011 à 20:29
Quelques commentaires :
-1
Code : Sélectionner tout
  for (i = 0; str[i] == ' ' && str[i]; i++);
le second test est inutile : si str[i] == ' ' alors str[i] != 0

-2
Code : Sélectionner tout
1
2
3
4
5
  for (; str[i]; i++) 
  { 
      if (str[i] != ' ') 
      .... 
      else if (str[i] == ' ' && str[i + 1] != ' ' && str[i])
str[i] est toujours dans le else égal à ' ' (et donc aussi != 0 ce qui de plus était déjà testé dans le for englobant)

-3 Erreur dans le realloc() :
Code : Sélectionner tout
 res = realloc(res, y+1);
Le realloc doit aussi être fait par la procédure utilisée par fearyourself

-4 Ne traite pas correctement les blancs en queue de chaine (en laisse un)

-----------------------------------
Une version qui fait la chose sur place en modifiant la chaine d'origine :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void epur(char* chaine) 
{ 
  int blanc  = 1; 
  char* lire = chaine; 
  char* ecrire = chaine; 
  while(*lire != '\0') 
  { 
    if(*lire != ' ' || !blanc)*ecrire++ = *lire; 
    blanc = *lire ==' '; 
    lire++; 
  } 
  if(blanc && ecrire != chaine) ecrire--; 
  *ecrire = '\0'; 
}
Avatar de cyberboss cyberboss - Membre à l'essai https://www.developpez.com
le 11/01/2011 à 15:02
Bonjour,

Merci pour tes remarques :

1- Oui c'est vrai, faute d'inatention voila ce que c'est de coder trop vite sans tout verifier =)

2- comment ca "str[i] est toujours dans le else égal à ' '" si str[i] est une lettre il rentre dans le premier if ?? (et pour les str[i] != 0 je voulai ecrire str[i + 1], ce qui nous enleve le probleme 4)

3- au temps pour moi j'ai pas l'habitude des realloc =)

4- Probleme reglee au 2-

Et merci pour les commentaires.
Sinon je viens de tester mon code marche donc bien avec le str[i + 1] et en corigeant le realloc.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
char    *epur(char *str) 
{ 
  char  *res; 
  int   i; 
  int   y; 
 
  y = 0; 
  res = malloc((strlen(str) + 1) * sizeof(char)); 
  if (res == NULL) 
    return (NULL); 
  for (i = 0; str[i] == ' ' && str[i]; i++); 
  for (; str[i]; i++) 
    { 
      if (str[i] != ' ') 
        { 
          res[y] = str[i]; 
          y++; 
        } 
      else if (str[i] == ' ' && str[i + 1] != ' ' && str[i + 1]) 
        { 
          res[y] = ' '; 
          y++; 
        } 
    } 
  res[y] = 0; 
  return (res); 
}
Avatar de D[r]eadLock D[r]eadLock - Membre éclairé https://www.developpez.com
le 11/01/2011 à 22:30
Mes 2 centimes:
- diogene, je ne comprends pas ton || &&, il manque peut-être des parenthèses (et même, le != ' ' && == ' ' s'annule non ?)
- cyberboss le else du str[i] != ' ' implique forcément que str[i] == ' '

Allez, à moi, à moi:
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <string.h> 
#include <stdlib.h> 
 
char *epur(const char *s) 
{ 
	char *new, *p; 
	if (!s || !(new = p = strdup(s))) 
		return NULL; 
	for (; *s; ++s) { 
		/* on a un caractère non-blanc, ou alors le prochain l'est (et on n'est pas au debut) */ 
		if (*s != ' ' || (*(s+1) && *(s+1) != ' ' && p != new)) 
			*(p++) = *s; 
	} 
	*p = '\0'; 
	/* on pourrait très bien ici faire `return new;` */ 
	if ((p = realloc(new, p+1-new))) 
		new = p; 
	return new; 
}
PS: c'est néanmoins marrant de voir les différents styles ;D
Avatar de gl gl - Rédacteur https://www.developpez.com
le 11/01/2011 à 22:48
Citation Envoyé par D[r]eadLock  Voir le message
Mes 2 centimes:
- diogene, je ne comprends pas ton || &&, il manque peut-être des parenthèses (et même, le != ' ' && == ' ' s'annule non ?)

Non, dans l'exemple de diogene, les deux tests ne s'annulent pas. && est prioritaire sur || ainsi

Code : Sélectionner tout
if(*lire != ' ' || !blanc && *lire == ' ')
est équivalent à

Code : Sélectionner tout
if(*lire != ' ' || (!blanc && *lire == ' '))
Personnellement, même si ça reste simple à lire dans un tel cas, j'aurais plutôt tendance à mettre les parenthèses.
Avatar de D[r]eadLock D[r]eadLock - Membre éclairé https://www.developpez.com
le 14/01/2011 à 21:31
Citation Envoyé par gl  Voir le message
Code : Sélectionner tout
if(*lire != ' ' || (!blanc && *lire == ' '))

Du coup ça revient à (et ce que j'entendais par s'annulent, et j'avoue que "simplifient" aurait été plus approprié):
Code : Sélectionner tout
if (*lire != ' ' || !lblanc)
Avatar de gl gl - Rédacteur https://www.developpez.com
le 14/01/2011 à 22:48
Citation Envoyé par D[r]eadLock  Voir le message
Du coup ça revient à (et ce que j'entendais par s'annulent, et j'avoue que "simplifient" aurait été plus approprié):
Code : Sélectionner tout
if (*lire != ' ' || !lblanc)

Au temps pour moi, je n'avais pas compris le "s'annulent" dans ce sens là.
Avatar de diogene diogene - Expert éminent sénior https://www.developpez.com
le 15/01/2011 à 18:58
Vous avez raison
Je modifie mon post en conséquence.
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.
Contacter le responsable de la rubrique C