C – dividir la cadena en una matriz de cadenas

3 minutos de lectura

No estoy completamente seguro de cómo hacer esto en C:

char* curToken = strtok(string, ";");
//curToken = "ls -l" we will say
//I need a array of strings containing "ls", "-l", and NULL for execvp()

¿Cómo haría para hacer esto?

  • Si desea dividir en función de los espacios, ¿por qué ha especificado ; como delimitador?

    –Oliver Charlesworth

    25 de junio de 2012 a las 23:03

  • Por ejemplo: cadena = “ls -l; fecha; conjunto +v”

    – Jordania

    25 de junio de 2012 a las 23:05

avatar de usuario
Filip Roséen – árbitro

Como ya has investigado strtok simplemente continúe por el mismo camino y divida su cadena usando el espacio (' ') como delimitador, luego use algo como realloc para aumentar el tamaño de la matriz que contiene los elementos que se van a pasar a execvp.

Vea el siguiente ejemplo, pero tenga en cuenta que strtok modificará la cadena que se le pasó. Si no desea que esto suceda, debe hacer una copia de la cadena original, utilizando strcpy o función similar.

char    str[]= "ls -l";
char ** res  = NULL;
char *  p    = strtok (str, " ");
int n_spaces = 0, i;


/* split string and append tokens to 'res' */

while (p) {
  res = realloc (res, sizeof (char*) * ++n_spaces);

  if (res == NULL)
    exit (-1); /* memory allocation failed */

  res[n_spaces-1] = p;

  p = strtok (NULL, " ");
}

/* realloc one extra element for the last NULL */

res = realloc (res, sizeof (char*) * (n_spaces+1));
res[n_spaces] = 0;

/* print the result */

for (i = 0; i < (n_spaces+1); ++i)
  printf ("res[%d] = %s\n", i, res[i]);

/* free the memory allocated */

free (res);

res[0] = ls
res[1] = -l
res[2] = (null)

  • @JordanCarney me alegro de ser de servicio.

    – Filip Roséen – árbitro

    25 de junio de 2012 a las 23:20

  • @FilipRoséen-refp ¿Puede explicar el último bloque de código antes de imprimir y liberar la memoria, el: /* realloc one extra element for the last NULL */? me cuesta entenderlo

    – Honinbo Shusaku

    16/10/2015 a las 20:49

  • @Abdul, creo que generalmente hay un carácter nulo al final de cada matriz para que la computadora pueda diferenciar entre dos matrices diferentes.

    – Charles

    18 de noviembre de 2015 a las 13:42

  • si envuelvo esto en una función y devuelvo el res puntero, recibo una advertencia después de liberar el puntero que asigné res a, diciendo: warning: attempt to free a non-heap object [-Wfree-nonheap-object]. ¿Tiene alguna idea de la causa?

    – MattSom

    2 de mayo de 2020 a las 9:23


Aquí hay un ejemplo de cómo usar strtok tomado de MSDN.

Y los bits relevantes, debe llamarlos varias veces. los token char* es la parte que colocarías en una matriz (puedes descifrar esa parte).

char string[] = "A string\tof ,,tokens\nand some  more tokens";
char seps[]   = " ,\t\n";
char *token;

int main( void )
{
    printf( "Tokens:\n" );
    /* Establish string and get the first token: */
    token = strtok( string, seps );
    while( token != NULL )
    {
        /* While there are tokens in "string" */
        printf( " %s\n", token );
        /* Get next token: */
        token = strtok( NULL, seps );
    }
}

  • Lo entiendo mucho, pero esto no me da una serie de cadenas de tokens. Supongo que no entiendo esa parte específica.

    – Jordania

    25 de junio de 2012 a las 23:09

  • Por qué token = strtok(NULL, seps);? Porqué el NULL?

    – Charles

    18 de noviembre de 2015 a las 13:47

  • @c650 Vea la página vinculada de MSDN, las llamadas posteriores necesitan la NULL.

    – Chris O.

    18 de noviembre de 2015 a las 16:51

  • Ah, sí, busqué mucho en Google y descubrí que strtok() utiliza una variable estática para guardar su lugar.

    – Charles

    18/11/2015 a las 19:35

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad