Finestre.  Virus.  I Quaderni.  Internet.  ufficio.  Utilità.  Autisti

Altro Alias

strtok

REVISIONE

#includere

char *strtok(char *str, const carattere *delimitare);
char *strtok_r(char *str, const carattere *delimitare, carattere **saveptr);

Requisiti delle macro di test delle proprietà per glibc (vedere feature_test_macro(7)):

strtok_r(): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

DESCRIZIONE

Funzione strtok() divide una stringa in una sequenza di zero o più token non vuoti. Alla prima chiamata strtok() la stringa analizzata deve essere specificata nell'argomento str. In ogni chiamata successiva che analizza la stessa stringa, il valore str deve essere NULLA.

In discussione delimitare imposta un set di byte che sono considerati separatori di token nella stringa analizzata. Il chiamante può specificare stringhe diverse in delimitare nelle chiamate successive durante l'analisi della stessa stringa.

Ogni chiamata strtok() restituisce un puntatore a una stringa con terminazione null che contiene il token successivo. Questa stringa non include il byte delimitatore. Se non ci sono più token, allora strtok() restituisce NULL.

Sequenza di chiamata strtok() che operano su una singola stringa mantiene un puntatore che specifica il punto in cui iniziare a cercare il token successivo. Prima chiamata strtok() assegna a questo puntatore un riferimento al primo byte della stringa. L'inizio del token successivo è determinato dalla ricerca in avanti str il byte successivo non è un delimitatore. Se viene trovato un byte, viene preso come inizio del token successivo. Se non viene trovato alcun byte di questo tipo, non ci sono più token e strtok() restituisce NULL (per una stringa vuota o composta solo da delimitatori in questo caso, NULL verrà restituito alla prima chiamata strtok()).

La fine di ogni token viene trovata da una ricerca in avanti che dura finché non viene trovato il byte delimitatore o il byte null di terminazione ("\0"). Se viene trovato un byte delimitatore, viene sostituito con un byte nullo per terminare il token corrente e strtok() memorizza un puntatore al byte successivo; questo puntatore verrà utilizzato come punto di partenza durante la ricerca del token successivo. In questo caso strtok() restituisce un puntatore all'inizio del token trovato.

Dalla descrizione precedente risulta che una sequenza di due o più byte delimitatori contigui in una stringa scansionata è considerata un delimitatore singolo e i byte delimitatori all'inizio o alla fine della stringa vengono ignorati. In altre parole, i token sono tornati strtok() - sempre no righe vuote. Cioè, ad esempio, se c'è una linea " aaa;;bbb,”, quindi chiamate successive strtok() con separatori di riga specificati " ;, ' restituirebbe le stringhe ' aaa" E " bbb' seguito da un puntatore nullo.

Funzione strtok_r() è la versione rientrante strtok(). Discussione saveptrè un puntatore a una variabile carattere* che viene utilizzato all'interno strtok_r() per tenere conto del contesto tra le chiamate successive durante l'analisi della stessa stringa.

Alla prima chiamata strtok_r() Senso str deve puntare alla stringa analizzata e al valore saveptr ignorato. Nelle chiamate successive, il valore str deve essere NULL e il valore saveptr non deve essere cambiato dalla chiamata precedente.

Più stringhe possono essere analizzate contemporaneamente su più esecuzioni strtok_r() con argomenti diversi saveptr.

VALORE DI RITORNO

Funzioni strtok() E strtok_r() restituisce un puntatore al token successivo o NULL se non ci sono più token.

ATTRIBUTI

Per una descrizione dei termini in questa sezione, cfr attributi(7).
Interfaccia Attributo Senso
strtok() innocuità nei filinon sicuro (MT-Unsafe race:strtok)
strtok_r() innocuità nei filiinnocuo (MT-Safe)

CONFORMITÀ

strtok() POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD. strtok_r() POSIX.1-2001, POSIX.1-2008.

DIFETTI

Usa queste funzionalità con cautela. Nota che: * Queste funzioni cambiano il loro primo argomento. * Queste funzioni non possono essere utilizzate con stringhe costanti. * L'identità del byte delimitatore viene persa. * Quando si analizza la funzione strtok() utilizza un buffer statico, quindi non è thread-safe. Utilizzo strtok_r() in questo caso.

ESEMPIO

Il programma seguente utilizza cicli nidificati che chiamano strtok_r() per suddividere la stringa nei suoi token costituenti. Nel primo parametro riga di comando viene data la stringa da analizzare. Il secondo parametro specifica i byte delimitatori, utilizzati per dividere la stringa in token "compositi". Il terzo parametro specifica i byte separatori utilizzati per separare i token "compositi" in token secondari.

Un esempio dell'output del programma:

$./a.out "a/bbb///cc;xxx:yyy:" ":;" "/" 1: a/bbb///cc --> a --> bbb --> cc 2: xxx --> xxx 3: yyy --> yyy

Codice sorgente del programma

#includere #includere #includere int main(int argc, char *argv) ( char *str1, *str2, *token, *subtoken; char *saveptr1, *saveptr2; int j; if (argc != 4) ( fprintf(stderr, "Utilizzo: % s stringa delim subdelim\n", argv); exit(EXIT_FAILURE); ) for (j = 1, str1 = argv; ; j++, str1 = NULL) ( token = strtok_r(str1, argv, &saveptr1); if (token = = NULL) break; printf("%d: %s\n", j, token); for (str2 = token; ; str2 = NULL) ( subtoken = strtok_r(str2, argv, &saveptr2); if (subtoken == NULL) break; printf(" --> %s\n", subtoken); ) ) exit(EXIT_SUCCESS); )

Un altro esempio di un programma che utilizza strtok() può essere trovato in getaddrinfo_a(3).

4 risposte

Due cose da sapere su strtok . Come accennato, "mantiene lo stato interno". Inoltre lui ha incasinato la linea che le dai da mangiare. Essenzialmente scriverà "\0" dove troverà il marcatore che hai fornito e restituirà un puntatore all'inizio della stringa. Internamente mantiene la posizione dell'ultimo token; e la prossima volta che lo chiamerai, ricomincerà da lì.

Una conseguenza importante è che non puoi usare strtok su una stringa come const char* "hello world"; , poiché otterrai una violazione di accesso quando cambi il contenuto di una stringa const char*.

La "cosa buona" di strtok è che in realtà non copia le stringhe, quindi non devi gestire l'allocazione di memoria aggiuntiva, ecc. Ma se non capisci quanto sopra, avrai problemi ad usarlo.

Esempio. Se hai "this, is, string", le chiamate successive a strtok genereranno puntatori come segue (il valore ^ è il valore restituito). Si noti che "\0" viene aggiunto dove si trovano i token; questo significa che la riga originale è cambiata:

T h i s , i s , a , s t r i n g \0 this,is,a,string t h i s \0 i s , a , s t r i n g \0 this ^ t h i s \0 i s \0 a , s t r i n g \0 is ^ t h i s \0 i s \0 a \ 0 s t r io n g \0 un ^ t h io s \0 io s \0 un \0 s t r io n g \0 stringa ^

Spero che questo abbia senso.

La funzione strtok() memorizza i dati tra le chiamate. Usa questi dati quando lo chiami con un puntatore NULL.

Il punto in cui è stato trovato l'ultimo token viene archiviato internamente con una funzione da utilizzare nella chiamata successiva (non è richiesta alcuna implementazione specifica della libreria per evitare arresti anomali dei dati).

strtok mantiene lo stato interno. Quando lo chiami con non NULL, si reinizializza per utilizzare la stringa che fornisci. Quando lo chiami con NULL , usa quella stringa e qualsiasi altro stato che ha attualmente per restituire il token successivo.

A causa del modo in cui funziona strtok, devi assicurarti di collegarti alla versione multi-thread del runtime C se stai scrivendo un'applicazione multi-thread. Ciò garantisce che ogni thread ottenga il proprio stato interno per strtok .

La funzione strtok archivia i dati in una variabile statica interna condivisa tra tutti i thread.

Per la sicurezza del thread dovresti usare strtok_r

Dai un'occhiata a static char *last;

Char * strtok(s, delim) registro char *s; registro const char *delim; ( register char *spanp; register int c, sc; char *tok; static char *last; if (s == NULL && (s = last) == NULL) return (NULL); /* * Salta (span) iniziale delimitatori (s += strspn(s, delim), sorta di).*/ cont: c = *s++; for (spanp = (char *)delim; (sc = *spanp++) != 0;) ( if (c == sc) goto cont; ) if (c == 0) ( /* nessun carattere non delimitatore */ last = NULL; return (NULL); ) tok = s - 1; /* * Scansiona token (cerca delimitatori : s += strcspn(s, delim), una specie di).* Nota che delim deve avere un NUL; ci fermiamo se vediamo anche questo. */ for (;;) ( c = *s++; spanp = (char *)delim; do ( if ((sc = *spanp++) == c) ( if (c == 0) s = NULL; else s[-1] = 0; last = s; return (tok); ) ) while (sc != 0); ) /* NOTREACHED */ )

condividere

La funzione strtok() restituisce un puntatore al token successivo nella stringa puntata dal parametro str1. I caratteri che compongono la stringa indirizzata dal parametro str2 sono i delimitatori che definiscono il token. Se non è presente alcun token da restituire, viene restituito un puntatore nullo.

Nella versione C99, il qualificatore di limitazione viene applicato ai parametri str1 e str2.

Per dividere una stringa in token, la prima volta che viene chiamata la funzione strtok(), il parametro str1 deve puntare all'inizio di quella stringa. Nelle successive chiamate di funzione, deve essere utilizzato un puntatore nullo come parametro str1. In questo caso, la stringa completa verrà aggiornata ad ogni chiamata di funzione.

Ogni chiamata alla funzione strtok() può utilizzare un set diverso di separatori di token.

La funzione strtok() fornisce un mezzo per ridurre una stringa alle sue parti costitutive. Ad esempio, il programma seguente tokenizza la stringa "Uno, due e tre".

#includere #includere int main(void) char *p; p = strtok("Uno, due e tre.", ","); printf(p); do ( p = strtok(NULL, ",. "); if(p) printf("|%s", p); ) while(p), return 0; )

L'output di questo programma è il seguente.

uno | due | e | tre

Si noti come la funzione strtok() venga inizialmente chiamata con la stringa originale, ma le chiamate successive utilizzino NULL come primo argomento. La funzione strtok() mantiene un puntatore interno alla stringa da elaborare. Se il primo argomento di strtok() punta a una stringa, il puntatore interno viene impostato all'inizio di quella stringa. Se il primo argomento è uguale al valore NULL, la funzione strtok() continua l'elaborazione della riga precedente, a partire dalla posizione memorizzata nel passaggio precedente, e fa avanzare il puntatore interno man mano che viene ricevuto il token successivo. Pertanto, la funzione strtok() "attraversa" l'intera stringa. Si noti inoltre come la stringa delimitatrice cambia durante la prima e le successive chiamate alla funzione. I delimitatori possono essere definiti in modo diverso su ciascuna chiamata.

char far * far _fstrtok(const char far *str1, const char far *str2)

Descrizione:

La funzione strtok() restituisce un puntatore al token successivo nella stringa puntata da str1. I caratteri della stringa puntata da str2 vengono utilizzati come delimitatori che definiscono il token. Se il token non viene trovato, viene restituito NULL.

La prima chiamata a strtok() utilizza effettivamente str1 come puntatore. Le chiamate successive utilizzano NULL come primo argomento. Quindi l'intera stringa può essere tokenizzata.

È importante capire che la funzione strtok() modifica la stringa puntata da str1. Ogni volta che viene trovato un token, viene inserito un carattere nullo nella posizione in cui è stato trovato il delimitatore. Quindi strtok() avanza lungo la stringa.

Con ogni chiamata a strtok(), puoi variare il set di delimitatori.

La funzione _fstrtok() è la versione FAR della funzione in questione.

Il seguente programma tokenizza la stringa "The summer soldier, the sunshine patriot" utilizzando spazi e virgole come delimitatori. Come risultato del programma, verrà generata una riga del seguente modulo: “The | estate | soldati | il | sole | patriota".
#includere
#includere
int principale(vuoto)
{
carattere*p;
p = strtok( "Il soldato dell'estate, il patriota del sole", " " ) ;
printf(p);
Fare(
p=strtok(" \0 " , ", " ) ;
if (p) printf("|%s" , p) ;
) mentre (p);
ritorno 0 ;
}

I linguaggi di programmazione possono includere funzioni speciali lavorare con le stringhe, evitando così al programmatore di dover scrivere le proprie funzioni di elaborazione delle stringhe. Ad esempio, spesso è necessario determinare la lunghezza di una stringa, e quindi i linguaggi forniscono una funzione per misurarne la lunghezza.

Nel linguaggio di programmazione C, le funzioni per lavorare con le stringhe sono dichiarate nel file di intestazione string.h, che devi ricordarti di includere nel tuo codice sorgente. Ci sono una ventina di funzioni per lavorare con le stringhe. Tra questi ci sono quelli che cercano caratteri in una stringa, funzioni di confronto, copia di stringhe, oltre a quelli più specifici. Elenco e descrizione della maggior parte degli esistenti questo momento nel linguaggio C, le funzioni si trovano nell'appendice del libro di B. Kernighan, D. Ritchie "The C Programming Language. Second Edition".

Tutte le funzioni dichiarate in string.h possono o meno modificare una delle stringhe passate dal puntatore nel corso del loro lavoro. Dipende dallo scopo della funzione. Tuttavia, la maggior parte di essi restituisce qualcosa: un puntatore a un carattere o un numero intero. Inoltre, se la funzione cambia uno dei suoi parametri ed è stata chiamata per questo, ciò che restituisce può essere ignorato (cioè non assegnato a nulla nella funzione chiamante).

Ad esempio, la funzione strcpy() ha la seguente dichiarazione: char *strcpy (char *, const char*) . Copia la stringa puntata dal secondo parametro nella stringa puntata dal primo parametro. Quindi il primo parametro è cambiato. Inoltre, la funzione restituisce un puntatore al primo carattere della stringa:

carattere s1[ 10 ] , s2[ 10 ] ; carattere*s3; s3 = s2; ottiene (s1) ; s3 = strcpy (s2, s1) ; mette (s2) ; mette (s3) ; printf("%p,%p \N", s2, s3) ;

Qui s2 e s3 puntano allo stesso carattere (printf() emette lo stesso indirizzo). Tuttavia, ciò che restituisce strcpy() non può essere assegnato a un array. Il risultato di questa funzione di solito non è assegnato a nulla; a volte è sufficiente che cambi semplicemente una delle stringhe passate dal puntatore.

Un'altra cosa sono funzioni come strlen() o strcmp() , che non modificano i parametri, ma vengono chiamate per amore del risultato. La funzione strcmp() confronta le due stringhe di argomenti lettera per lettera (lessicograficamente) e restituisce 0, -1 o 1. Ad esempio, chiamando strcmp("boy", "body") restituirà 1 perché codice lettera "y" più di una lettera"D". Chiamare strcmp("body", "boy") restituirà -1, perché il primo argomento è lessicograficamente inferiore al secondo.

funzione strtok()

Usando la funzione strtok(), puoi dividere una stringa in parti separate (token). La dichiarazione di questa funzione è simile a questa char *strtok (char *, const char *) . La prima volta che viene chiamata la funzione, il primo parametro è la stringa da dividere. Il secondo parametro specifica la stringa delimitatrice. Nelle successive chiamate di funzione per la stessa riga, il primo parametro deve essere NULL, perché la funzione ha già "ricordato" con cosa lavora. Considera un esempio:

char str = "uno, due, tre, quattro, cinque" ; char*sp; sp = strtok (str, ", " ); while (sp) ( mette (sp) ; sp = strtok (NULL, ", " ) ; )

Come risultato dell'esecuzione di questo codice, le seguenti parole vengono visualizzate in una colonna:

uno due tre quattro cinque

La prima volta che viene chiamato strtok(), alla funzione viene passato un puntatore al primo carattere dell'array e una stringa delimitatrice. Dopo questa chiamata, l'array str viene modificato, rimane solo la parola "uno" e la funzione restituisce anche un puntatore a questa parola, che è assegnata a sp.

Sebbene abbiamo perso il resto dell'array nella funzione chiamante, un puntatore al resto dell'array viene mantenuto all'interno di strtok(). Quando viene passato NULL, la funzione "sa" lavorare con quella coda.

Copia di parti di stringhe

Quando devi solo unire due stringhe, il problema si risolve facilmente chiamando la funzione strcat(), che aggiunge il secondo alla fine del primo argomento. Una funzione simile, strncat(), aggiunge n caratteri dalla seconda stringa alla prima. n è specificato come terzo parametro.

E se la situazione è più complessa? Ad esempio, ci sono due righe non vuote ed è necessario collegare l'inizio della prima e la fine della seconda. Puoi farlo usando la funzione strcpy(), se passi i riferimenti non ai primi caratteri delle stringhe:

char s1[ 20 ] = "Peter Smith" , s2 = "Julia Roberts" ; strcpy (s1+ 5 , s2+ 5 ) ; mette(s1) ;

IN questo caso Sullo schermo verrà visualizzato "Peter Roberts". Perchè è successo? Alla funzione strcpy() è stato passato un puntatore al sesto carattere della prima stringa. Ciò ha portato al fatto che durante la copia i caratteri di questa stringa vengono sovrascritti solo a partire dal 6, perché strcpy() non "sa" nulla dei caratteri precedenti. Anche solo una parte della stringa viene passata come secondo argomento, che viene copiato nel primo.

Come inserire una riga nel mezzo di un'altra? Puoi risolvere questo problema utilizzando la terza riga "buffer", dove puoi prima copiare la prima riga, poi la seconda, sovrascrivendo la fine della prima, quindi allegare la fine della prima. Ma puoi anche fare così:

char s1[ 20 ] = "uno tre" , s2[ 20 ] = "due" ; strcpy (s2+ 3 , s1+ 3 ) ; strcpy (s1+ 4 , s2) ; mette(s1) ;

Qui, prima, la fine del primo viene copiata nella seconda riga, risulta "due tre". Quindi la seconda riga viene copiata sulla prima riga, ignorandone l'inizio.

Descrizione di alcune funzioni per lavorare con le stringhe

Esercizio
Di seguito sono riportate le descrizioni di alcune funzioni che eseguono operazioni sulle stringhe. Progettare e scrivere piccoli programmi che illustrino come funzionano queste funzioni.

  • char *strchr (const char *, int c) . Restituisce un puntatore alla prima occorrenza del carattere c nella stringa. Restituisce NULL se nella stringa non è presente alcun carattere di questo tipo.
  • char *strstr (const char *s2, const char *s1) . Restituisce un puntatore alla prima occorrenza della stringa s1 nella stringa s2. Se non ci sono corrispondenze, restituisce NULL.
  • char *strncpy (char *, const char *, size_t n) . Copia n caratteri della seconda stringa nella prima.
  • size_t strspn (const char *, const char *) . Restituisce la lunghezza dell'inizio della prima stringa che include i caratteri che compongono la seconda stringa.

Se noti un errore, seleziona una parte di testo e premi Ctrl + Invio
CONDIVIDERE: