2010-03-15 25 views
7

Possibili duplicati:
Painless way to trim leading/trailing whitespace in C?
Trim a string in Cscrittura String.trim() in C

Ciao ragazzi, che stavo scrivendo il metodo assetto String in C e questo è il codice Mi sono inventato. Penso che faccia il lavoro di eliminare gli spazi bianchi iniziali e finali, vorrei che il codice fosse più pulito. Puoi suggerire miglioramenti.

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

Questo codice sembra pulito ??

+2

bene si controlla solo per l'* SPACE * carattere. Lo spazio bianco di solito consiste nel controllo di TAB, ritorno a capo e avanzamento riga –

+8

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

+0

aggiungere commenti potrebbe aiutare – Drakosha

risposta

4

Non sembra pulito. Supponendo che il primo carattere sia uno spazio, stai utilizzando lastc con un valore non definito. Stai lasciando uno spazio alla fine (se c'è uno spazio alla fine, quando viene colpito, lo c sarà uno spazio e non lo sarà lo lastc).

Non stai terminando la stringa. Supponendo di aver risolto il problema non inizializzato lastc, trasformerai "abc" in "abcbc", poiché non viene abbreviato in alcun punto.

Il codice consente inoltre di comprimere più spazi all'interno della stringa. Questo non è quello che hai descritto; è il comportamento desiderato?

1

Ci sono diversi problemi con quel codice. Controlla solo lo spazio. Non tabulazioni o newline. Stai copiando l'intera parte non vuota dello spago. E stai usando lastc prima di impostarlo.

Ecco una versione alternativa (compilato ma non testato):

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

Invece di confrontare un personaggio con il carattere di spazio '', mi piacerebbe utilizzare la funzione "isspace", che a mio avviso è definito in ctype.h.

0

Non so su pulito, ma trovo difficile da seguire. Se avevo bisogno di fare questo avevo inizialmente penso in due fasi:

  1. Capire quanti caratteri a cadere fin dall'inizio, quindi memmove il resto della stringa (compreso il terminatore nullo) al punto di partenza indirizzo. (Potrebbe non essere necessario il memmove se è possibile restituire un puntatore di avvio diverso, ma in tal caso è necessario prestare molta attenzione all'igiene della memoria.)
  2. Calcolare il numero di caratteri da eliminare dalla (nuova) fine e impostare un nuovo terminatore null lì.

potrei poi guardare più da vicino ad una soluzione in un solo passaggio, come ti sembra di essere cercando di attuare, ma solo se ci fosse un problema di velocità.

A proposito, probabilmente si desidera utilizzare isspace() anziché controllare solo lo spazio.

1

Ci sono alcuni problemi: lastc potrebbe essere utilizzato non inizializzato. Ad esempio, potresti utilizzare un ciclo for invece di un ciclo while. Inoltre, le funzioni trim/strip di solito sostituiscono spazi, tabulazioni e newline.

Ecco una soluzione che utilizza indicatori che ho scritto un po 'di tempo fa:

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

Ecco la mia soluzione.

Breve, semplice, pulito, commentato e leggermente testato.

Utilizza la funzione di classificazione "isspace", quindi è possibile modificare facilmente la definizione di "spazio bianco" da ritagliare.

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

Questo potrebbe essere pericoloso quando strlen (String) è 0. – user85509

+0

C'è dell'altro spazio in più rispetto al carattere spaziale – Mawg

3

Spesso rende il codice più leggibile se si fanno uso giudizioso delle funzioni della libreria standard - per esempio, isspace() e memmove() sono particolarmente utili qui:

#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

Ho il permesso di usarlo nel software commerciale? – Mawg