Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: kutcher en 28 Julio 2014, 05:14 am



Título: Extraña asignación en un array con -1
Publicado por: kutcher en 28 Julio 2014, 05:14 am
 Buenas, estoy tratando de implementar mi propia función strtok y buscando por la
red he encontrado un método bastante curioso el cual utiliza el numero negativo
-1 como indice en un array de caracteres para asignarle el carácter nulo

 En consecuencia extrañamente obtienes el primer token en el puntero llamado
token, cosa que no entiendo como sucede aquí el código:

Código
  1. char *mystrtok(char *s, const char *delim)
  2. {
  3.    int c, sc = *delim;
  4.    char *token = s;
  5.  
  6.    do{
  7.        c = *s++;
  8.        if (c == sc)
  9.        {
  10.            s[-1] = '\0';
  11.            return (token);
  12.        }
  13.    }while (*s);
  14.  
  15.    return NULL;
  16. }

Es la versión corta la modifique un poquito para exponer la parte que no entiendo


Título: Re: Extraña asignación en un array con -1
Publicado por: CalgaryCorpus en 28 Julio 2014, 06:24 am
Genéricamente, la notacion que usa el parentesis cuadrado, como

p[ entero ]

es igual a

 * ( p + entero )

por lo que

 puntero[ -1 ]

es igual a

 *( puntero - 1 )

El codigo que muestras mueve a "s" un lugar hacia adelante unas lineas antes por lo que si se quiere acceder a posiciones previas el -1 tiene (algo de) sentido.


Título: Re: Extraña asignación en un array con -1
Publicado por: eferion en 28 Julio 2014, 11:30 am
Código
  1. c = *s++;

Es equivalente a:

Código
  1. c = *s;
  2. s++;

Es decir, asigno a 'c' el valor apuntado por 's' y después hago que 's' apunte al siguiente carácter.

Código
  1. if (c == sc)
  2. {
  3.  s[-1] = '\0';
  4. }

Si 'c' se corresponde con el delimitador, entonces tengo que eliminar ese delimitador... pero claro, el único puntero que tengo, 's', está apuntando al siguiente carácter... bueno, pues retrocedo una posición y listo.


Título: Re: Extraña asignación en un array con -1
Publicado por: kutcher en 28 Julio 2014, 16:23 pm
por lo que

 puntero[ -1 ]

es igual a

 *( puntero - 1 )

Viéndolo de esa forma todo tiene mas sentido, solo una ultima consulta luego de esta asignación la cadena s queda modificada no?


Título: Re: Extraña asignación en un array con -1
Publicado por: rir3760 en 28 Julio 2014, 17:00 pm
luego de esta asignación la cadena s queda modificada no?
Si. El propósito de la función es buscar un único carácter y sustituirlo con un cero, si ello sucede se retorna el primer parámetro, caso contrario se retorna NULL.

A esa función se deberían realizar algunos cambios ya que si se busca un solo carácter no tiene caso que el segundo parámetro sea un puntero y ya que las variables "c" y "sc" (deberían ser de tipo char, no hay necesidad de declararlas con el tipo int) solo "pasan la cubeta" se pueden eliminar. Por ultimo no tiene en cuenta el caso donde el primer parámetro es una cadena nula.

Quedaría así:
Código
  1. char *mystrtok(char *s, char delim)
  2. {
  3.   char *p = s;
  4.  
  5.   do {
  6.      if (*s == delim){
  7.         *s = '\0';
  8.         return p;
  9.      }
  10.   }while (*s++);
  11.  
  12.   return NULL;
  13. }

Un saludo


Título: Re: Extraña asignación en un array con -1
Publicado por: kutcher en 28 Julio 2014, 17:51 pm
Si. El propósito de la función es buscar un único carácter y sustituirlo con un cero, si ello sucede se retorna el primer parámetro, caso contrario se retorna NULL.

De ser así, porque al asignar la cadena s a una variable estática los caracteres posteriores al carácter nulo son asignados de igual manera a tal variable:

Código
  1. if (*s == delim){
  2.  *s = '\0';
  3.   *last = s; //<== Aqui luego de la supuesta modificación
  4.  return p;
  5. }


Título: Re: Extraña asignación en un array con -1
Publicado por: Blaster en 28 Julio 2014, 19:39 pm
De ser así, porque al asignar la cadena s a una variable estática los caracteres posteriores al carácter nulo son asignados de igual manera a tal variable:

Como ya te han indicado el puntero s al encontrarse el primer carácter delimitador ya apunta al siguiente carácter a partir del cual realizas la correspondiente asignación hasta el siguiente carácter nulo.


Título: Re: Extraña asignación en un array con -1
Publicado por: rir3760 en 28 Julio 2014, 21:18 pm
De ser así, porque al asignar la cadena s a una variable estática los caracteres posteriores al carácter nulo
En tu primer mensaje la función no tiene una variable con clase de almacenamiento estático, si actualizaste la función y te surge una duda por favor publica el código fuente completo.

Y si te interesa el tema de implementaciones propias de strtok puedes revisar varias de ellas en la discusión CRT personalizada (http://foro.elhacker.net/buscador-t386470.0.html).

Un saludo


Título: Re: Extraña asignación en un array con -1
Publicado por: kutcher en 28 Julio 2014, 21:41 pm
por favor publica el código fuente completo.

Disculpa, este es el código original que he encontrado:

Código
  1. char *
  2. strtok(char *s, const char *delim)
  3. {
  4.    static char *last;
  5.  
  6.    return strtok_r(s, delim, &last);
  7. }
  8.  
  9. char *
  10. strtok_r(char *s, const char *delim, char **last)
  11. {
  12.    char *spanp;
  13.    int c, sc;
  14.    char *tok;
  15.  
  16.    if (s == NULL && (s = *last) == NULL)
  17.        return (NULL);
  18.  
  19.    tok = s;
  20.    for (;;)
  21.    {
  22.        c = *s++;
  23.        spanp = (char *)delim;
  24.        do
  25.        {
  26.            if ((sc = *spanp++) == c)
  27.            {
  28.                if (c == 0)
  29.                    s = NULL;
  30.                else
  31.                    s[-1] = 0;
  32.                *last = s;
  33.                return (tok);
  34.            }
  35.        }
  36.        while (sc != 0);
  37.    }
  38. }
  39.  

Creo que es la implementación de la función estándar strtok