συναρτήσεις strtok. Πώς λειτουργεί η συνάρτηση strtok στο C; Παράδειγμα: πηγαίος κώδικας προγράμματος

Άλλο ψευδώνυμο

strtok

ΑΝΑΣΚΟΠΗΣΗ

#περιλαμβάνω

char *strok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim,απανθρακώνω**saveptr);

Απαιτήσεις για τη μακροεντολή ελέγχου ιδιοτήτων για το glibc (βλ feature_test_macros(7)):

strtok_r(): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_ΠΗΓΗ || _POSIX_SOURCE

ΠΕΡΙΓΡΑΦΗ

Λειτουργία strtok() χωρίζει μια συμβολοσειρά σε μια ακολουθία μηδενικών ή περισσότερων μη κενών διακριτικών. Στην πρώτη κλήση strtok() η συμβολοσειρά που θα αναλυθεί πρέπει να προσδιορίζεται στο όρισμα str. Σε κάθε επόμενη κλήση που αναλύει την ίδια συμβολοσειρά, η τιμή strπρέπει να είναι NULL.

Σε επιχειρηματολογία delimκαθορίζεται ένα σύνολο byte που θεωρούνται διαχωριστικά διακριτικών στην αναλυόμενη συμβολοσειρά. Ο καλών μπορεί να καθορίσει διαφορετικές γραμμές delimσε επόμενες κλήσεις κατά την ανάλυση της ίδιας συμβολοσειράς.

Κάθε κλήση strtok() επιστρέφει έναν δείκτη σε μια συμβολοσειρά με μηδενικό τερματισμό που περιέχει το επόμενο διακριτικό. Αυτή η γραμμή δεν περιλαμβάνει byte οριοθέτη. Αν δεν υπάρχουν άλλα διακριτικά, τότε strtok() επιστρέφει NULL.

Ακολουθία κλήσεων strtok(), που λειτουργούν σε μία μόνο συμβολοσειρά, διατηρεί έναν δείκτη που καθορίζει το σημείο στο οποίο ξεκινά η αναζήτηση για το επόμενο διακριτικό. Πρώτη κλήση strtok() εκχωρεί σε αυτόν τον δείκτη μια αναφορά στο πρώτο byte της συμβολοσειράς. Η έναρξη του επόμενου διακριτικού καθορίζεται με αναζήτηση προς τα εμπρός strτο επόμενο byte δεν είναι οριοθέτης. Εάν βρεθεί ένα byte, λαμβάνεται ως αρχή του επόμενου διακριτικού. Εάν δεν βρεθεί ένα τέτοιο byte, τότε δεν υπάρχουν άλλα διακριτικά και strtok() επιστρέφει NULL (για μια κενή ή οριοθετημένη συμβολοσειρά, οπότε το NULL θα επιστραφεί την πρώτη φορά που καλείται strtok()).

Το τέλος κάθε διακριτικού βρίσκεται με μια αναζήτηση προς τα εμπρός μέχρι να βρεθεί ένα byte οριοθέτησης ή ένα μηδενικό byte ("\0"). Εάν βρεθεί ένα byte οριοθέτησης, αντικαθίσταται με ένα μηδενικό byte για να τερματιστεί το τρέχον διακριτικό και strtok() αποθηκεύει έναν δείκτη στο επόμενο byte. αυτός ο δείκτης θα χρησιμοποιηθεί ως σημείο εκκίνησης κατά την αναζήτηση του επόμενου διακριτικού. Σε αυτήν την περίπτωση strtok() επιστρέφει έναν δείκτη στην αρχή του διακριτικού που βρέθηκε.

Από την παραπάνω περιγραφή, προκύπτει ότι μια ακολουθία δύο ή περισσότερων συνεχόμενων bytes οριοθέτη στη γραμμή που σαρώνεται θεωρείται ένας μεμονωμένος οριοθέτης και αγνοούνται τα bytes Delimiter στην αρχή ή στο τέλος της συμβολοσειράς. Με άλλα λόγια, οι μάρκες επέστρεψαν strtok() - πάντα μη κενές χορδές. Δηλαδή, για παράδειγμα, εάν υπάρχει μια γραμμή " ααα;;bbb,», μετά επόμενες κλήσεις strtok() με δεδομένους διαχωριστές γραμμών " ;, "θα επέστρεφε τις χορδές" ααα" Και " bbb" και μετά έναν μηδενικό δείκτη.

Λειτουργία strtok_r() είναι η έκδοση επανεισόδου strtok(). Διαφωνία saveptrείναι ένας δείκτης σε μια μεταβλητή χαρ *που χρησιμοποιείται εσωτερικά strtok_r() για να λαμβάνεται υπόψη το πλαίσιο μεταξύ των επόμενων κλήσεων κατά την ανάλυση της ίδιας συμβολοσειράς.

Στην πρώτη κλήση strtok_r() νόημα strπρέπει να δείχνει τη συμβολοσειρά που αναλύεται και την τιμή saveptrαγνόησε. Σε επόμενες κλήσεις η τιμή strπρέπει να είναι NULL και η τιμή saveptrδεν πρέπει να αλλάξει από την προηγούμενη κλήση.

Διαφορετικές σειρές μπορούν να αναλυθούν ταυτόχρονα σε πολλαπλές εκτελέσεις strtok_r() με διαφορετικά επιχειρήματα saveptr.

ΑΞΙΑ ΕΠΙΣΤΡΟΦΗΣ

Λειτουργίες strtok() Και strtok_r() επιστρέψτε έναν δείκτη στο επόμενο διακριτικό ή NULL εάν δεν υπάρχουν άλλα διακριτικά.

ΓΝΩΡΙΣΜΑΤΑ

Για περιγραφή των όρων σε αυτήν την ενότητα, βλ γνωρίσματα(7).
Διεπαφή Χαρακτηριστικό Εννοια
strtok() ακίνδυνη στα νήματαμη ασφαλής (MT-Μη ασφαλής αγώνας:strtok)
strtok_r() ακίνδυνη στα νήματααβλαβές (MT-Safe)

ΣΥΜΜΟΡΦΩΣΗ

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

ΕΛΑΤΤΩΜΑΤΑ

Χρησιμοποιήστε αυτές τις λειτουργίες με προσοχή. Σημειώστε ότι: * Αυτές οι συναρτήσεις τροποποιούν το πρώτο τους όρισμα. * Αυτές οι συναρτήσεις δεν μπορούν να χρησιμοποιηθούν με σταθερές συμβολοσειρές. * Η ταυτότητα του διαχωριστικού byte χάνεται. * Κατά την ανάλυση της συνάρτησης strtok() χρησιμοποιεί ένα στατικό buffer και επομένως δεν είναι ασφαλές για νήματα. Χρήση strtok_r() σε αυτήν την περίπτωση.

ΠΑΡΑΔΕΙΓΜΑ

Το παρακάτω πρόγραμμα χρησιμοποιεί ένθετους βρόχους για κλήση strtok_r() για να χωρίσετε μια συμβολοσειρά στα συστατικά της διακριτικά. Στην πρώτη παράμετρο γραμμή εντολώνκαθορίζεται η συμβολοσειρά που θα αναλυθεί. Η δεύτερη παράμετρος καθορίζει τα διαχωριστικά byte, τα οποία χρησιμοποιούνται για τη διαίρεση της συμβολοσειράς σε "σύνθετα" διακριτικά. Η τρίτη παράμετρος καθορίζει τα διαχωριστικά byte, τα οποία χρησιμοποιούνται για τον διαχωρισμό των "σύνθετων" διακριτικών σε δευτερεύοντα διακριτικά.

Παράδειγμα εξόδου προγράμματος:

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

Πηγαίος κώδικας προγράμματος

#περιλαμβάνω #περιλαμβάνω #περιλαμβάνω int main (int argc, char *argv) (char *str1, *str2, *token, *subtoken, char *saveptr1, *saveptr2; int j, if (argc! = 4) (fprintf (stderr, "χρήση: % s String delim subdelim \ n ", argv), exit (exit_failure);) για (j = 1, str1 = argv; j ++, str1 = null) = 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", δευτερεύον διακριτικό); ) ) έξοδος (EXIT_SUCCESS); )

Ένα άλλο παράδειγμα προγράμματος που χρησιμοποιεί strtok(), μπορεί να βρεθεί στο getaddrinfo_a(3).

Η συνάρτηση strtok() επιστρέφει έναν δείκτη στο επόμενο διακριτικό στη συμβολοσειρά που δείχνει η str1. Οι χαρακτήρες που συνθέτουν τη συμβολοσειρά που απευθύνεται από το str2 είναι οι οριοθέτες που ορίζουν το διακριτικό. Εάν δεν υπάρχει διακριτικό για επιστροφή, επιστρέφεται ένας μηδενικός δείκτης.

Στην έκδοση C99, ο προσδιορισμός περιορισμού εφαρμόζεται στις παραμέτρους str1 και str2.

Για να χωρίσετε μια συμβολοσειρά σε διακριτικά, την πρώτη φορά που καλείται η strtok(), η παράμετρος str1 πρέπει να δείχνει στην αρχή της συμβολοσειράς. Οι επόμενες κλήσεις στη συνάρτηση πρέπει να χρησιμοποιούν έναν μηδενικό δείκτη ως παράμετρο str1. Σε αυτήν την περίπτωση, η πλήρης συμβολοσειρά θα τροποποιείται κάθε φορά που καλείται η συνάρτηση.

Κάθε κλήση στη συνάρτηση strtok() μπορεί να χρησιμοποιήσει ένα διαφορετικό σύνολο οριοθετητών διακριτικών.

Η συνάρτηση strtok() παρέχει ένα μέσο για τη μείωση μιας συμβολοσειράς στα συστατικά της μέρη. Για παράδειγμα, το παρακάτω πρόγραμμα κάνει διακριτική τη συμβολοσειρά "Ένα, δύο και τρία".

#περιλαμβάνω #περιλαμβάνω int main(void) char *p; p = strtok("Ένα, δύο και τρία.", ","); printf(p); do ( p = strtok(NULL, ",. "); if(p) printf("|%s", p); ) while(p), return 0; )

Το αποτέλεσμα αυτού του προγράμματος είναι το εξής.

Ένα | δύο | και | τρία

Παρατηρήστε πώς λειτουργία strtokΤο () καλείται αρχικά με την αρχική συμβολοσειρά, αλλά οι επόμενες κλήσεις σε αυτήν χρησιμοποιούν το NULL ως πρώτο όρισμα. Η συνάρτηση strtok() διατηρεί έναν εσωτερικό δείκτη στη συμβολοσειρά που υποβάλλεται σε επεξεργασία. Εάν το πρώτο όρισμα της strtok() δείχνει σε μια συμβολοσειρά, ο εσωτερικός δείκτης ορίζεται στην αρχή αυτής της συμβολοσειράς. Εάν το πρώτο επιχείρημα είναι μηδενικό, το strtok () συνεχίζει την επεξεργασία της προηγούμενης συμβολοσειράς, ξεκινώντας από τη θέση που έμαθε στο προηγούμενο βήμα και προωθεί τον εσωτερικό δείκτη ως το επόμενο διακριτικό. Έτσι, η συνάρτηση strtok() "διασχίζει" ολόκληρη τη συμβολοσειρά. Προσέξτε επίσης πώς αλλάζει η συμβολοσειρά οριοθέτη στην πρώτη και στις επόμενες κλήσεις στη συνάρτηση. Οι οριοθέτες μπορεί να ορίζονται διαφορετικά για κάθε κλήση.

#περιλαμβάνω char *strok(char * str1, const char * str2);

Η συνάρτηση strtok() επιστρέφει έναν δείκτη στο επόμενο διακριτικό στη συμβολοσειρά που απευθύνεται από την παράμετρο str1. Χαρακτήρες που σχηματίζουν τη συμβολοσειρά που απευθύνεται από την παράμετρο str2, είναι οριοθέτες που ορίζουν ένα διακριτικό. Εάν δεν υπάρχει διακριτικό για επιστροφή, επιστρέφεται ένας μηδενικός δείκτης.

Στην έκδοση C99 στις παραμέτρους str1Και str2Εφαρμόζεται ο προσδιορισμός περιορισμού.

Για να χωρίσετε μια συμβολοσειρά σε διακριτικά, την πρώτη φορά που καλείτε τη strtok(), την παράμετρο str1πρέπει να δείχνει στην αρχή αυτής της γραμμής. Σε επόμενες κλήσεις στη συνάρτηση ως παράμετρος str1πρέπει να χρησιμοποιήσετε έναν μηδενικό δείκτη. Με αυτόν τον τρόπο, ολόκληρη η συμβολοσειρά χωρίζεται σε διακριτικά.

Κάθε κλήση στη συνάρτηση strtok() μπορεί να χρησιμοποιεί διαφορετικό σύνολο οριοθέτες.

Παράδειγμα

Αυτό το πρόγραμμα σπάει τη συμβολοσειρά «Το γρασίδι είναι πράσινο, ο ήλιος λάμπει» σε διακριτικά που χωρίζονται με κενά και κόμματα. Το αποτέλεσμα θα είναι

Το γρασίδι|γίνεται πράσινο|ήλιος|λάμπει #περιλαμβάνω #περιλαμβάνω int main(void) ( char *p; p = strtok("Το γρασίδι είναι πράσινο, ο ήλιος λάμπει", " "); printf(p); do ( p = strtok("\0", ", ") ; if(p ) printf("|%s", p); ) while(p); return 0; )

Σύνταξη:

#περιλαμβάνω
char *strtok(char *str, const char *sep);

Επιχειρήματα:

str – δείκτης στη συμβολοσειρά που θα χωριστεί.
sep – δείκτης σε μια συμβολοσειρά που περιέχει ένα σύνολο χαρακτήρων οριοθέτη.

Επιστρεφόμενη τιμή:

NULL – εάν η συμβολοσειρά δεν μπορεί να χωριστεί σε μέρη.
Ένας δείκτης στον πρώτο χαρακτήρα του επιλεγμένου τμήματος της συμβολοσειράς.

Περιγραφή:

Η συνάρτηση STRTOK επιλέγει το επόμενο τμήμα της συμβολοσειράς που υποδεικνύεται από το επιχείρημα STR, χωρισμένο από έναν από τους χαρακτήρες οριοθέτησης που καθορίζονται στη συμβολοσειρά που υποδεικνύεται από το επιχείρημα SEP. Διαδοχικές κλήσεις στη συνάρτηση strtok έχουν ως αποτέλεσμα τη διάσπαση της συμβολοσειράς σε μέρη (tokens).

«Η πρώτη κλήση στη συνάρτηση strtok καθορίζει την αρχή της συμβολοσειράς που θα διαιρεθεί (str) και την αρχή της συμβολοσειράς που περιέχει διαχωριστικά (sep). Η συνάρτηση strtok ξεκινά κοιτάζοντας τους χαρακτήρες της συμβολοσειράς str έναν κάθε φορά και αναζητώντας έναν χαρακτήρα που δεν περιέχεται στην οριοθετημένη συμβολοσειρά sep. Εάν στη συμβολοσειρά str ο χαρακτήρας τέλους γραμμής συναντηθεί πριν βρεθεί ένας χαρακτήρας που δεν περιλαμβάνεται στη συμβολοσειρά sep, τότε η συμβολοσειρά str δεν μπορεί να χωριστεί σε μέρη και επιστρέφεται ένας μηδενικός δείκτης (NULL). Εάν βρεθεί ένας τέτοιος χαρακτήρας, θεωρείται ότι είναι η αρχή του πρώτου μέρους της χορδής."

Στη συνέχεια, η συνάρτηση strtok αναζητά το διαχωριστικό, δηλαδή τον χαρακτήρα που περιλαμβάνεται στη συμβολοσειρά sep. Εάν δεν βρεθεί ένας τέτοιος χαρακτήρας, τότε η συμβολοσειρά str θεωρείται ότι αποτελείται από ένα μέρος και οι επακόλουθες διασπάσεις της συμβολοσειράς str θα επιστρέψουν έναν μηδενικό δείκτη. Αν βρεθεί τέτοιο σύμβολο. τότε αντικαθίσταται με έναν μηδενικό χαρακτήρα (χαρακτήρας τέλους γραμμής). Στη συνέχεια, η συνάρτηση strtok θυμάται την τρέχουσα θέση (έναν δείκτη του χαρακτήρα από τον οποίο θα ξεκινήσει η αναζήτηση για το επόμενο τμήμα της γραμμής) και επιστρέφει έναν δείκτη στην αρχή του πρώτου επιλεγμένου τμήματος της γραμμής.

Εάν η συνάρτηση strtok επέστρεψε έναν μη μηδενικό δείκτη, μπορείτε να συνεχίσετε να χωρίζετε τη συμβολοσειρά σε κομμάτια. Για να συνεχιστεί ο διαχωρισμός της συμβολοσειράς, καλείται ξανά η συνάρτηση strtok, αλλά αντί για δείκτη στη συμβολοσειρά που πρόκειται να διαχωριστεί, ορίζεται NULL ως η πρώτη αύξηση. Σε αυτήν την περίπτωση, η συνάρτηση strtok θα συνεχίσει να χωρίζεται από την απομνημονευμένη διεύθυνση. Ο αλγόριθμος κατάτμησης θα παραμείνει ο ίδιος.

Παράδειγμα:

Στο παράδειγμα, η συμβολοσειρά "test1/test2/test3/test4" χωρίζεται σε μέρη χρησιμοποιώντας τον οριοθέτη "/" χρησιμοποιώντας τη συνάρτηση strtok. Το αποτέλεσμα του διαχωρισμού βγαίνει στην κονσόλα.

Αποτέλεσμα:

Έξοδος κονσόλας:





Μπλουζα