Appearance
strtok
cpp
#include <cstring>
char* strtok(char* s, char* sep);strtokvine de la string + token (bucata).- Scop: extrage pe rand token-urile (bucatile de text) dintr-un sir, ignorand separatorii.
- Un separator este orice caracter care apare in sirul
sep.
Cum functioneaza
Vom numi caracter-cuvant orice caracter ce NU este separator
strtokmereu cauta prima adresa unde ar gasi un caracter-cuvantaceea va fi adresa pe care o returnam
dupa ce a gasit acea adresa
- cauta prima adresa unde am separator
- acolo va pune caracterul
\0- e sfarsitul de cuvant
si tine intern o adresa curenta (variabila "ascunsa").
Primul apel:
strtok(s, sep)— se da sirul.Apelurile urmatoare:
strtok(NULL, sep)—NULLinseamna "continua de unde ai ramas".Cand nu mai sunt tokeni: returneaza
NULL.
Exemplu pas cu pas
Sirul initial: ,.,ana are,..,mere.,
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| s | , | . | , | a | n | a | a | r | e | , | . | . | , | m | e | r | e | . | , | \0 |
| apel | parametru | token returnat | adresa returnata |
|---|---|---|---|
| 1 | s | "ana" | s + 3 |
| 2 | NULL | "are" | s + 7 |
| 3 | NULL | "mere" | s + 14 |
| 4 | NULL | — | NULL |
Sirul s dupa toate apelurile (separatorii devin '\0'):
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| s | , | . | , | a | n | a | \0 | a | r | e | \0 | . | . | , | m | e | r | e | \0 | , | \0 |
Atentie
strtok modifica sirul original. Daca ai nevoie de el dupa parcurgere, fa o copie cu strcpy inainte.
Idiom de parcurgere
cpp
char* p;
p = strtok(s, sep);
while (p != NULL)
{
cout << p << '\n';
p = strtok(NULL, sep);
}Echivalent cu for:
cpp
char* p;
for (p = strtok(s, sep); p != NULL; p = strtok(NULL, sep))
{
cout << p << '\n';
}Exemplu complet
cpp
#include <iostream>
#include <cstring>
using namespace std;
char s[] = "ana,are.mere,si.pere";
char sep[] = ",.";
char* p;
int main()
{
for (p = strtok(s, sep); p != NULL; p = strtok(NULL, sep))
{
cout << p << '\n';
}
return 0;
}Afisare:
ana
are
mere
si
pereImplementare proprie
cpp
char* mytok(char* s, char* sep)
{
static char* urmatorul = NULL;
char* token;
int i, j;
bool continuiLaUrmatorul = s == NULL;
if (continuiLaUrmatorul)
{
s = urmatorul;
if (urmatorul == NULL)
{
return NULL;
}
}
bool esteSeparator;
token = NULL;
for (i = 0; s[i] != '\0'; i++)
{
esteSeparator = strchr(sep, s[i]) != NULL;
if (!esteSeparator)
{
token = s + i;
break;
}
}
if (token == NULL)
{
// am ajuns la finalul sirului
// si nu am apucat sa ii dau lui token o adresa a unui non-separator
// deci NU am inceput de token
return NULL;
}
for (j = i + 1; s[j] != '\0'; j++)
{
esteSeparator = strchr(sep, s[j]) != NULL;
if (esteSeparator)
{
s[j] = '\0';
urmatorul = s + j + 1;
return token;
}
}
// pana la finalul sirului (unde am \0 )
// NU s-a mai gasit vreun separator
// deci acest token este sufix pentru sirul meu
// si la urmatorul strtok(), SIGUR NU va mai fi vreun token
urmatorul = NULL;
return token;
}