Pregunta

Me acabo de escribir un programa que tokenizes una matriz de caracteres utilizando punteros. El programa sólo necesita trabajar con un espacio como un carácter delimitador. Acabo de cumplir en y tengo todo el crédito, pero después de entregarlo me di cuenta de que este programa Sólo funcionaba si el carácter delimitador era un espacio.

Mi pregunta es, ¿cómo podría hacer que este programa de trabajo con cada carácter delimitador?

La función He mostrado a continuación devuelve un puntero a la siguiente palabra en la matriz de caracteres. Esto es lo que creo que tengo que cambiar si se va a trabajar con todos los caracteres delimitadores.

Gracias!

Código:

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

El bucle de impresión en principal:

// this loop will display the tokens
while ( ( nextWord = tk.Next ( ) ) != NULL )
{
    cout << nextWord << endl;
}
¿Fue útil?

Solución

La forma más simple es cambiar su

while (*pStart != delim)

a algo como

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

O, usted podría hacer delim una cadena, y crear una función que comprueba si un char es en la cadena:

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

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

O, tal vez la mejor solución es utilizar una de las funciones prediseñados para hacer todo esto, como strtok .

Otros consejos

Sólo cambia

while (*pStart != delim)

a esta línea

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

Función strchr Estándar (declarada en la cabecera string.h) busca un carácter de (dado como segundo argumento) en un C-secuencia (dado como primer argumento) y devuelve puntero a la cadena desde la posición donde se produce en primer lugar que el carácter. Así strchr(" \t\n", *pStart) == NULL significa que el carácter actual (*pStart) no se encuentra en " \t\n" cadena y que no es un delimitador! (Cambie esta " \t\n" cadena delimitadora para adaptarlo a sus necesidades, por supuesto.)

Esta solución es la forma breve y sencilla para comprobar si da carácter en un conjunto (generalmente pequeña) de personajes interesantes dadas. Y utiliza la función estándar.

Por cierto, usted puede hacer esto utilizando no sólo C-secuencia, pero con std::string también. Todo lo que necesita es declarar const std::string con valor " \t\n" similar y luego vuelva a colocar strchr con el método find de la cadena delimitadora declarado.

Hmm ... esto no se ve del todo bien:

if (*pStart = '\0')

La condición nunca puede ser verdad. Supongo que pretendía == en lugar de =? También tiene un poco de un problema aquí:

while (*pStart != delim)

Si la última palabra de la cadena no es seguido por un delimitador, esto va a funcionar fuera de la final de la cadena, lo que provocará problemas serios.

Edit: A menos que realmente necesita hacer esto por su cuenta, considere el uso de un stringstream para el trabajo. Ya cuenta con todo el mecanismo de la derecha en su lugar y muy fuertemente a prueba. Se le añade por encima, pero es bastante aceptable en muchos casos.

No es compilado. pero me gustaría hacer algo como esto.

 //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).

Asumo que queremos mantener a C en lugar de C ++. Funciones strspn y strcspn son buenos para tokenizing por un conjunto unos delimitadores. Se puede utilizar para encontrar strspn donde comienza el siguiente separador (es decir donde termina el token actual) y luego usando strcspn de encontrar donde los extremos del separador (es decir, cuando comienza el siguiente token). Bucle hasta que llegue al final.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top