strtok în C

Împarte un șir în bucăți (tokeni) după unul sau mai multe caractere separatoare, modificând șirul original.

Sintaxă
#include <string.h>
char *strtok(char *s, const char *separatori);

Ce face strtok

La primul apel îi dai șirul: strtok(linie, ","). Funcția găsește primul token, înlocuiește separatorul de după el cu '\0' și întoarce un pointer la token. La apelurile următoare dai NULL în loc de șir, iar strtok continuă de unde a rămas. Când nu mai sunt tokeni, întoarce NULL.

Separatorii sunt un set de caractere: " ,;" înseamnă „spațiu, virgulă sau punct și virgulă”. Separatorii consecutivi sunt tratați ca unul singur, deci câmpurile goale ("a,,b") dispar.

strtok modifică șirul și ține poziția într-o variabilă internă. Nu îl poți folosi pe un literal și nici pentru două șiruri în paralel (de exemplu în bucle imbricate). Pe sisteme POSIX există strtok_r, care primește poziția ca argument.

Parametri

Parametru Descriere
s Șirul de împărțit (un tablou modificabil) la primul apel, NULL la următoarele.
separatori Caracterele care despart tokenii.

Ce returnează

Pointer la următorul token sau NULL când nu mai sunt.

Exemple

Exemplul 1: Cuvintele dintr-o propoziție

#include <stdio.h>
#include <string.h>

int main(void) {
    char text[] = "Ana  are mere, pere;prune";
    for (char *t = strtok(text, " ,;"); t != NULL; t = strtok(NULL, " ,;")) {
        printf("[%s]\n", t);
    }
    return 0;
}

Rezultat

[Ana]
[are]
[mere]
[pere]
[prune]

Exemplul 2: Câmpurile unei linii CSV simple

După împărțire, șirul original conține terminatori în locul virgulelor: printf pe el afișează doar primul câmp.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char linie[] = "Ion,Cluj,9";
    char *nume = strtok(linie, ",");
    char *oras = strtok(NULL, ",");
    char *nota = strtok(NULL, ",");
    if (nume && oras && nota) {
        printf("%s din %s are nota %d\n", nume, oras, atoi(nota));
    }
    printf("Linia acum: %s\n", linie);
    return 0;
}

Rezultat

Ion din Cluj are nota 9
Linia acum: Ion

Greșeli frecvente

  • Apelezi strtok pe un literal: strtok("a,b", ","). Literalul nu poate fi modificat; copiază-l întâi într-un tablou (char s[] = "a,b";).
  • Apelezi din nou cu șirul în loc de NULL și primești la nesfârșit primul token.
  • Te aștepți la câmpuri goale pentru "Ana,,Iași": strtok sare peste separatorii consecutivi.

Comenzi înrudite

  • strchr și strrchr: Caută un caracter într-un șir: strchr găsește prima apariție, strrchr pe ultima.
  • strstr: Caută prima apariție a unui subșir într-un șir și întoarce un pointer la ea sau NULL.
  • strcpy, strncpy și strdup: Copiază un șir C într-un alt tablou (strcpy, strncpy) sau într-o zonă nouă alocată cu malloc (strdup).
  • atoi, atol și atof: Transformă rapid textul de la începutul unui șir într-un număr, fără să semnaleze erori.
  • fgets: Citește un rând întreg (cu tot cu spații) într-un tablou de caractere, fără să depășească dimensiunea dată.