Domanda

Ho appena scritto un programma che tokenizza un array di caratteri utilizzando i puntatori. Il programma aveva bisogno solo di lavorare con uno spazio come un carattere di delimitazione. Ho appena compiuto dentro e ho piena di credito, ma dopo aver girato in mi sono reso conto che questo programma solo ha funzionato se il carattere delimitatore era uno spazio.

La mia domanda è, come potrei fare questo lavoro di programma con ogni carattere di delimitazione?

La funzione vi ho mostrato qui di seguito restituisce un puntatore alla parola successiva nella matrice char. Questo è ciò che credo ho bisogno di cambiare se si tratta di lavorare con tutti i caratteri di delimitazione.

Grazie!

Codice:

char* StringTokenizer::Next(void)
{
pNextWord = pStart;

if (*pStart == '\0') { return NULL; }

while (*pStart != delim)
{
    pStart++;
}

if (*pStart == '\0') { return NULL; }

*pStart = '\0';
pStart++;

return pNextWord;
}

Il ciclo di stampa in principale:

// this loop will display the tokens
while ( ( nextWord = tk.Next ( ) ) != NULL )
{
    cout << nextWord << endl;
}
È stato utile?

Soluzione

Il modo più semplice è quello di cambiare il tuo

while (*pStart != delim)

a qualcosa di simile

while (*pStart != ' ' && *pStart != '\n' && *pStart != '\t')

In alternativa, si potrebbe fare delim una stringa, e creare una funzione che controlla se un char è nella stringa:

bool isDelim(char c, const char *delim) {
   while (*delim) {
      if (*delim == c)
         return true;
      delim++;
   }
   return false;
}

while ( !isDelim(*pStart, " \n\t") ) 

O, forse la soluzione migliore è quella di utilizzare una delle funzioni pre-compilate per fare tutto questo, come ad esempio strtok .

Altri suggerimenti

Basta cambiare

while (*pStart != delim)

a questa linea

while (*pStart != '\0' && strchr(" \t\n", *pStart) == NULL)

funzione strchr standard (dichiarati nell'intestazione string.h) cerca un carattere (dato come secondo argomento) in una C-stringa (dato come primo argomento) e restituisce puntatore alla stringa dalla posizione in cui tale carattere si verifica in primo luogo. Così strchr(" \t\n", *pStart) == NULL significa che il carattere corrente (*pStart) non si trova in " \t\n" corda e che non è un delimitatore! (Modificare questa " \t\n" stringa delimitatore per adattarlo alle proprie esigenze, ovviamente.)

Questa soluzione è il modo breve e semplice per verificare se dato carattere in un set (solitamente di piccole dimensioni) di determinati personaggi interessanti. E si utilizza la funzione standard.

A proposito, è possibile farlo utilizzando non solo C-string, ma con std::string troppo. Tutto ciò che serve è di dichiarare const std::string con valore " \t\n"-like e quindi sostituire strchr con il metodo find della stringa delimitatore dichiarato.

Hmm ... questo non sembra giusto:

if (*pStart = '\0')

La condizione non può mai essere vero. Sto indovinando si intende == invece di =? Hai anche un po 'un problema qui:

while (*pStart != delim)

Se l'ultima parola nella stringa non è seguita da un delimitatore, questo sta per scappare alla fine della stringa, che causerà seri problemi.

Edit: A meno che non si ha realmente bisogno di fare questo da soli, è consigliabile utilizzare uno stringstream per il lavoro. E 'già tutto il meccanismo proprio nel luogo e piuttosto pesantemente testato. Lo fa aggiungere in testa, ma è abbastanza accettabile in molti casi.

Non compilato. ma mi piacerebbe fare qualcosa di simile.

 //const int N = someGoodValue;
char delimList[N] = {' ',',','.',';', '|', '!', '$', '\n'};//all delims here.

char* StringTokenizer::Next(void)
{
    if (*pStart == '\0') { return NULL; }

    pNextWord = pStart;

    while (1){  
        for (int x = 0; x < N; x++){
            if (*pStart == delimList[x]){ //this is it.
                *pStart = '\0';
                pStart++;
                return pNextWord;
            }

        }
        if ('\0' == *pStart){ //last word.. maybe.
                return pNextWord;   
        }
        pStart++;
    }
}

// (!compiled).

presumo che vogliamo aderire al C invece di C ++. Funzioni strspn e strcspn sono buoni per la creazione di token da un insieme un delimitatori. È possibile utilizzare strspn per trovare dove inizia la successiva separazione (vale a dire in cui il token corrente termina) e quindi utilizzando strcspn di trovare in cui il separatore estremità (vale a dire dove inizia il token successivo). Loop fino ad arrivare alla fine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top