2010-03-15 8 views
7

duplicados posibles:
Painless way to trim leading/trailing whitespace in C?
Trim a string in Cescritura String.trim() en C

Hola chicos, que estaba escribiendo el método de ajuste de cadena en C y este es el código Se me ocurrio. Creo que hace el trabajo de eliminar espacios en blanco iniciales y finales, sin embargo, desearía que el código fuera más limpio. ¿Puedes sugerir mejoras?

void trim(char *String) 
{ 
int i=0;j=0; 
char c,lastc; 
while(String[i]) 
{ 
    c=String[i]; 
    if(c!=' ') 
    { 
    String[j]=c; 
    j++; 
    } 
    else if(lastc!= ' ') 
    { 
    String[j]=c; 
    j++; 

    } 
    lastc = c; 
    i++; 
} 

¿Este código se ve limpio?

+2

bien que sólo comprueba el * ESPACIO * personaje. El espacio en blanco generalmente consiste en buscar TAB, retorno de carro y salto de línea –

+8

http://stackoverflow.com/questions/122616/painless-way-to-trim-leadingtrailing-whitespace-in-c –

+0

Agregar comentarios ayuda – Drakosha

Respuesta

4

No se ve limpio. Suponiendo que el primer carácter es un espacio, está usando lastc con un valor indefinido. Estás dejando un espacio al final (si hay un espacio al final, cuando se golpea c será un espacio y lastc no).

No está terminando la cadena. Asumiendo que resuelva el problema no inicializado lastc, transformará "abc" en "abcbc", ya que no se acorta en ningún momento.

El código también contrae varios espacios dentro de la cadena. Esto no es lo que describes; ¿es el comportamiento deseado?

1

Existen varios problemas con ese código. Solo busca espacio. No pestañas o nuevas líneas. Está copiando toda la parte de la cadena que no es en blanco. Y está usando lastc antes de configurarlo.

Aquí hay una versión alternativa (compilado pero no probado):

char *trim(char *string) 
{ 
    char *start; 
    int len = strlen(string); 
    int i; 

    /* Find the first non whitespace char */ 
    for (i = 0; i < len; i++) { 
     if (! isspace(string[i])) { 
      break; 
     } 
    } 

    if (i == len) { 
     /* string is all whitespace */ 
     return NULL; 
    } 

    start = &string[i]; 

    /* Remove trailing white space */ 
    for (i = len; i > 0; i--) { 
     if (isspace(string[i])) { 
      string[i] = '\0'; 
     } else { 
      break; 
     } 
    } 

    return start; 
} 
0

En lugar de comparar un carácter con el carácter de espacio '', que haría uso de la función "isspace", que creo que se define en ctype.h.

0

No sé sobre limpieza, pero me parece difícil de seguir. Si necesitaba hacer esto yo creo inicialmente de la misma en dos fases:

  1. calcular la cantidad de caracteres a caer desde el principio, entonces memmove el resto de la cadena (incluyendo el terminador nulo) al inicio dirección. (Es posible que no necesite el memmove si puede devolver un puntero de inicio diferente, pero si es así, debe tener mucho cuidado con la higiene de la memoria.)
  2. Determine cuántos caracteres debe caer del (nuevo) extremo y establecer un nuevo terminador nulo allí.

Podría ver más de cerca una solución de una pasada como la que parece estar intentando implementar, pero solo si hubiera un problema de velocidad.

Por cierto, es probable que desee utilizar isspace() en lugar de marcar solo por espacio.

1

Existen algunos problemas: lastc podría utilizarse sin inicializar. Y podría hacer uso de un bucle for en lugar de un bucle while, por ejemplo. Además, las funciones de recorte/banda generalmente reemplazan espacios, pestañas y nuevas líneas.

Aquí es una solución el uso de punteros que escribí hace bastante tiempo:

void trim(char *str) 
{ 
    char *ptr = str; 
    while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') ++ptr; 

    char *end = ptr; 
    while(*end) ++end; 

    if(end > ptr) 
    { 
     for(--end; end >= ptr && (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n'); --end); 
    } 

    memmove(str, ptr, end-ptr); 
    str[end-ptr] = 0; 
} 
1

Aquí está mi solución.

Corto, simple, limpio, comentado y probado ligeramente.

Utiliza la función de clasificación "isspace", por lo que puede cambiar fácilmente su definición de "espacio en blanco" para recortar.

void trim(char* String) 
{ 
    int dest; 
    int src=0; 
    int len = strlen(String); 

    // Advance src to the first non-whitespace character. 
    while(isspace(String[src])) src++; 

    // Copy the string to the "front" of the buffer 
    for(dest=0; src<len; dest++, src++) 
    { 
     String[dest] = String[src]; 
    } 

    // Working backwards, set all trailing spaces to NULL. 
    for(dest=len-1; isspace(String[dest]); --dest) 
    { 
     String[dest] = '\0'; 
    } 
} 
+0

Esto podría ser peligroso cuando strlen (String) es 0. – user85509

+0

Hay más en el espacio en blanco que el espacio charachter – Mawg

3

A menudo hace que el código sea más legible si hace uso juicioso de las funciones de la librería estándar - por ejemplo, isspace() y memmove() son particularmente útiles aquí:

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

void trim(char *str) 
{ 
    char *start, *end; 

    /* Find first non-whitespace */ 
    for (start = str; *start; start++) 
    { 
     if (!isspace((unsigned char)start[0])) 
      break; 
    } 

    /* Find start of last all-whitespace */ 
    for (end = start + strlen(start); end > start + 1; end--) 
    { 
     if (!isspace((unsigned char)end[-1])) 
      break; 
    } 

    *end = 0; /* Truncate last whitespace */ 

    /* Shift from "start" to the beginning of the string */ 
    if (start > str) 
     memmove(str, start, (end - start) + 1); 
} 
+1

¿Tengo su permiso para usar esto en un software comercial? – Mawg

Cuestiones relacionadas