συναρτήσεις strtok. Περιγραφή συναρτήσεων της γλώσσας C. Περιγραφή ορισμένων λειτουργιών για εργασία με χορδές

4 απαντήσεις

Δύο πράγματα που πρέπει να γνωρίζετε για το strtok. Όπως αναφέρθηκε, «διατηρεί εσωτερική κατάσταση». Επιπλέον, αυτός χάλασε τη γραμμή που το τροφοδοτείς. Ουσιαστικά θα γράψει "\0" όπου θα βρει το διακριτικό που παρείχατε και θα επιστρέψει έναν δείκτη στην αρχή της γραμμής. Εσωτερικά διατηρεί τη θέση του τελευταίου διακριτικού. και την επόμενη φορά που θα το καλέσετε, θα ξεκινήσει από εκεί.

Μια σημαντική συνέπεια είναι ότι δεν μπορείτε να χρησιμοποιήσετε το strtok σε μια συμβολοσειρά όπως το const char* "hello world"; αφού θα λάβετε παραβίαση πρόσβασης όταν αλλάζετε τα περιεχόμενα μιας συμβολοσειράς const char*.

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

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

T h i s , i s , a , s t r i n g \0 αυτό, είναι, a, string t h i s \0 i s , a , s t r i n g \0 αυτό ^ t h i s \0 i s \0 a , s t r i n g \0 είναι ^ t \0 i h i 0 s t r i n g \0 a ^ t h i s \0 i s \0 a \0 s t r i n g \0 συμβολοσειρά ^

Ελπίζω ότι αυτό έχει νόημα.

Η συνάρτηση strtok() αποθηκεύει δεδομένα μεταξύ των κλήσεων. Χρησιμοποιεί αυτά τα δεδομένα όταν τα καλείτε με δείκτη NULL.

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

Το strtok διατηρεί εσωτερική κατάσταση. Όταν το καλείτε με μη NULL, επαναδημιουργείται για να χρησιμοποιήσει τη συμβολοσειρά που παρέχετε. Όταν το καλείτε με NULL, χρησιμοποιεί αυτή τη συμβολοσειρά και οποιαδήποτε άλλη κατάσταση έχει αυτήν τη στιγμή για να επιστρέψει το επόμενο διακριτικό.

Λόγω του τρόπου με τον οποίο λειτουργεί το strtok, πρέπει να βεβαιωθείτε ότι έχετε συνδέσει με την έκδοση πολλαπλών νημάτων του χρόνου εκτέλεσης C εάν γράφετε μια εφαρμογή πολλαπλών νημάτων. Αυτό διασφαλίζει ότι κάθε νήμα αποκτά τη δική του εσωτερική κατάσταση για το strtok.

Η συνάρτηση strtok αποθηκεύει δεδομένα σε μια εσωτερική στατική μεταβλητή που μοιράζεται μεταξύ όλων των νημάτων.

Για την ασφάλεια του νήματος θα πρέπει να χρησιμοποιήσετε το strtok_r

Ρίξτε μια ματιά στο static char *last;

Char * strtok(s, delim) register char *s; εγγραφή const char *delim; ( εγγραφή char *spanp; εγγραφή int c, sc; char *tok; στατικό char *last; if (s == NULL && (s = τελευταίο) == NULL) επιστροφή (NULL); /* * Παράλειψη (span) στην αρχή οριοθέτες (s += strspn(s, delim), είδος == sc) if (c == 0) ( /* χωρίς χαρακτήρες οριοθέτησης */ last = NULL; return (NULL); ) tok = s - 1 /* Scan token (σάρωση για οριοθέτες : s += strcspn (s, delim) * Σημειώστε ότι το delim πρέπει να έχει ένα NUL. )delim; (sc != 0 ) /* NOTREACHED */ )

μερίδιο

1) Βρίσκει το επόμενο διακριτικό στη συμβολοσειρά byte με μηδενικό τερματισμό που δείχνει το str . Οι χαρακτήρες οριοθέτησης αναγνωρίζονται από τη συμβολοσειρά null byte που δείχνει το delim.

Αυτή η συνάρτηση ονομάζεται πολλαπλός πολλαπλασιασμός για να ληφθούν διαδοχικά διακριτικά από την ίδια συμβολοσειρά.

  • Αν στρ! = NULL str! = NULL, η κλήση αντιμετωπίζεται ως η πρώτη κλήση προς το strtok για τη συγκεκριμένη σειρά. Η συνάρτηση αναζητά τον πρώτο χαρακτήρα που Δενπου περιέχονται στο delim.
  • Εάν δεν βρέθηκε ένα τέτοιο σύμβολο, τότε δεν υπάρχουν διακριτικά σε αυτό και η συνάρτηση επιστρέφει έναν μηδενικό δείκτη.
  • Αν βρεθεί ένα τέτοιο σύμβολο, θα είναι έναρξη του διακριτικού. Στη συνέχεια, η συνάρτηση αναζητά από εκείνο το σημείο τον πρώτο χαρακτήρα που περιέχεται στο delim.
    • Εάν δεν βρεθεί τέτοιος χαρακτήρας, το str έχει μόνο ένα διακριτικό και οι μελλοντικές κλήσεις στο strtok επιστρέφουν έναν μηδενικό δείκτη
    • Εάν βρεθεί ένα τέτοιο σύμβολο, αυτό αντικαταστάθηκεο μηδενικός χαρακτήρας "\0" και ο δείκτης στον επόμενο χαρακτήρα αποθηκεύονται σε μια στατική θέση για επόμενες κλήσεις.
  • Στη συνέχεια, η συνάρτηση επιστρέφει έναν δείκτη στην αρχή του διακριτικού
  • Εάν str == NULL , η κλήση αντιμετωπίζεται σαν επόμενες κλήσεις προς το strtok: η συνάρτηση συνεχίζει από εκεί που έφυγε στην προηγούμενη κλήση. Η συμπεριφορά είναι η ίδια όπως εάν ο προηγουμένως αποθηκευμένος δείκτης είχε περάσει ως str .

Η συμπεριφορά είναι απροσδιόριστη, εκτός εάν το str ή το delim είναι δείκτης σε μια συμβολοσειρά byte με μηδενικό τερματισμό.

2) Ίδιο με το (1) εκτός από το ότι κάθε βήμα γράφει τον αριθμό των χαρακτήρων που απομένουν για να φαίνονται στο str στο *strmax και γράφει την εσωτερική κατάσταση του tokenizer σε *ptr . Οι επαναλαμβανόμενες κλήσεις (με μηδενικό strmax) πρέπει να περάσουν τα strmax και ptr με τις τιμές που αποθηκεύτηκαν από την προηγούμενη κλήση. Επιπλέον, τα ακόλουθα σφάλματα παρουσιάζονται κατά το χρόνο εκτέλεσης και η τρέχουσα εγκατεστημένη συνάρτηση χειριστή περιορισμών καλείται χωρίς να αποθηκεύεται τίποτα στο αντικείμενο που δείχνει το ptr

  • δείκτης strmax , delim ή ptr - null
  • σε περίπτωση μη αρχικής κλήσης (με null str), *ptr - null pointer
  • στην πρώτη κλήση *strmax είναι μηδέν ή μεγαλύτερο από RSIZE_MAX
  • η αναζήτηση για το τέλος του διακριτικού φτάνει στο τέλος της αρχικής συμβολοσειράς (όπως μετράται με την αρχική τιμή *strmax)) χωρίς να συναντήσετε έναν τερματιστή μηδενικού

Η συμπεριφορά είναι απροσδιόριστη εάν και το str δείχνει σε έναν πίνακα χαρακτήρων που δεν έχει μηδενικό χαρακτήρα και το strmax δείχνει σε μια τιμή μεγαλύτερη από το μέγεθος αυτού του πίνακα χαρακτήρων. Όπως όλες οι συναρτήσεις που σχετίζονται με τα όρια, η strtok_s είναι εγγυημένη ότι είναι διαθέσιμη μόνο εάν το __STDC_LIB_EXT1__ έχει οριστεί από την υλοποίηση και εάν ο χρήστης ορίσει __STDC_WANT_LIB_EXT1__ για την ακέραια σταθερά 1 πριν συμπεριλάβει το string.h .

επιλογές

Επιστρεφόμενη αξία

Επιστρέφει έναν δείκτη στην αρχή του επόμενου διακριτικού ή NULL εάν δεν υπάρχουν άλλα διακριτικά.

Το σημείωμα

Αυτή η συνάρτηση είναι καταστροφική: γράφει "\0" χαρακτήρες στα στοιχεία της συμβολοσειράς str . Ειδικότερα, η κυριολεκτική συμβολοσειρά δεν μπορεί να χρησιμοποιηθεί ως το πρώτο όρισμα για το strtok .

Κάθε κλήση στο strtok τροποποιεί μια στατική μεταβλητή: δεν είναι ασφαλής σε νήματα.

Σε αντίθεση με τα περισσότερα άλλα tokenizers, οι οριοθέτες του strtok μπορεί να είναι διαφορετικοί για κάθε επόμενο διακριτικό και μπορεί ακόμη και να εξαρτώνται από τα περιεχόμενα των προηγούμενων διακριτικών.

Η συνάρτηση strtok_s διαφέρει από τη συνάρτηση POSIX strtok_r στο ότι αποθηκεύεται εκτός της συμβολοσειράς με διακριτικό και ελέγχει για περιορισμούς χρόνου εκτέλεσης.

παράδειγμα

#define __STDC_WANT_LIB_EXT1__ 1 #include #περιλαμβάνω int main(void) ( char input = "Ένα πουλί κατέβηκε στη βόλτα"; printf("Αναλύοντας τη συμβολοσειρά εισόδου "%s"\n", είσοδος); char *token = strtok(input, " "); while( token) ( puts(token); token = strtok(NULL, " "); ) printf("Περιεχόμενα της συμβολοσειράς εισόδου τώρα: ""); for(size_t n = 0; n< sizeof input; ++n) input[n] ? printf("%c", input[n]) : printf("\\0"); puts("""); #ifdef __STDC_LIB_EXT1__ char str = "A bird came down the walk"; rsize_t strmax = sizeof str; const char *delim = " "; char *next_token; printf("Parsing the input string "%s"\n", str); token = strtok_s(str, &strmax, delim, &next_token); while(token) { puts(token); token = strtok_s(NULL, &strmax, delim, &next_token); } printf("Contents of the input string now: ""); for(size_t n = 0; n < sizeof str; ++n) str[n] ? printf("%c", str[n]) : printf("\\0"); puts("""); #endif }

Πιθανή έξοδος:

Ανάλυση της συμβολοσειράς εισόδου "Ένα πουλί κατέβηκε τη βόλτα" Ένα πουλί κατέβηκε τη βόλτα Περιεχόμενα της συμβολοσειράς εισόδου τώρα: "Ένα\0πουλάκι\0κατέβη\0κάτω\0η\0περπάτημα\0" Ανάλυση της συμβολοσειράς εισόδου "Ένα πουλί κατέβηκε το περπάτημα" Ένα πουλί κατέβηκε το περπάτημα Περιεχόμενα της συμβολοσειράς εισόδου τώρα: "Ένα\0πουλί\0κατέβη\0κάτω\0η\0βόλτα\0"

  • C11 (ISO/IEC 9899:2011):
    • 7.24.5.8 Συνάρτηση strtok (σελ: 369-370)
    • K.3.7.3.1 Συνάρτηση strtok_s (σελ: 620-621)
  • C99 (ISO/IEC 9899:1999):
    • 7.21.5.8 Συνάρτηση strtok (σελ: 332-333)
  • C89/C90 (ISO/IEC 9899:1990):
    • 4.11.5.8 συνάρτηση strtok
βρίσκει την πρώτη θέση οποιουδήποτε χαρακτήρα σε μια γραμμή, σε μια άλλη γραμμή
(λειτουργία)

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

(C95) (C11)

βρίσκει το επόμενο διακριτικό σε μια φαρδιά χορδή
(λειτουργία)
Τεκμηρίωση C++για στρτοκ

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

strtok

ΑΝΑΣΚΟΠΗΣΗ

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

char *strtok(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() επιστρέφει έναν δείκτη στην αρχή του διακριτικού που βρέθηκε.

Από την παραπάνω περιγραφή, προκύπτει ότι μια ακολουθία δύο ή περισσότερων συνεχόμενων byte οριοθέτη στη γραμμή που σαρώνεται θεωρείται ένας μοναδικός οριοθέτης και τα byte οριοθέτη στην αρχή ή στο τέλος της συμβολοσειράς αγνοούνται. Με άλλα λόγια, οι μάρκες επέστρεψαν 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); ) for (j = 1, str1 = argv; ; j++, str1 = NULL) ( token = strtok_r(str1, argv, &saveptr1); if (token = = NULL) break; NULL) break; printf(" --> %s\n", subtoken) ) exit(EXIT_SUCCESS)

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

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

Στη γλώσσα προγραμματισμού C, οι συναρτήσεις για εργασία με συμβολοσειρές δηλώνονται στο αρχείο κεφαλίδας string.h, το οποίο πρέπει να θυμάστε να συμπεριλάβετε στον πηγαίο κώδικα. Υπάρχουν περίπου είκοσι λειτουργίες για εργασία με χορδές. Ανάμεσά τους υπάρχουν εκείνα που αναζητούν χαρακτήρες σε μια συμβολοσειρά, συναρτήσεις σύγκρισης, συμβολοσειρές αντιγραφής, καθώς και πιο συγκεκριμένοι. Λίστα και περιγραφή των περισσότερων υπαρχόντων αυτή τη στιγμήΟι συναρτήσεις στη γλώσσα C βρίσκονται στο παράρτημα του βιβλίου των B. Kernighan, D. Ritchie “The C Programming Language”.

Όλες οι συναρτήσεις που δηλώνονται στο string.h, κατά τη διάρκεια της εργασίας τους, μπορούν να αλλάξουν ή να μην αλλάξουν μία από τις συμβολοσειρές που περνάει ο δείκτης. Εξαρτάται από τον σκοπό της λειτουργίας. Ωστόσο, τα περισσότερα από αυτά επιστρέφουν κάτι: είτε έναν δείκτη σε έναν χαρακτήρα είτε έναν ακέραιο. Επιπλέον, εάν μια συνάρτηση αλλάξει μια από τις παραμέτρους της και κλήθηκε για αυτόν τον σκοπό, τότε αυτό που επιστρέφει μπορεί να αγνοηθεί (δηλαδή, να μην εκχωρηθεί σε τίποτα στη συνάρτηση κλήσης).

Για παράδειγμα, η συνάρτηση strcpy() έχει την ακόλουθη δήλωση: char *strcpy (char *, const char*) . Αντιγράφει τη συμβολοσειρά που δείχνει η δεύτερη παράμετρος στη συμβολοσειρά που δείχνει η πρώτη παράμετρος. Έτσι αλλάζει η πρώτη παράμετρος. Επιπλέον, η συνάρτηση επιστρέφει έναν δείκτη στον πρώτο χαρακτήρα της συμβολοσειράς:

char s1[ 10] , s2[ 10] ; char * s3; s3 = s2; παίρνει(s1); s3 = strcpy(s2, s1); βάζει (s2) ; βάζει (s3) ; printf("%p, %p \n", s2, s3) ;

Εδώ τα s2 και s3 δείχνουν στο ίδιο σύμβολο (η printf() βγάζει τις ίδιες διευθύνσεις). Ωστόσο, το τι επιστρέφει η strcpy() δεν μπορεί να εκχωρηθεί σε έναν πίνακα. Το αποτέλεσμα αυτής της λειτουργίας συνήθως δεν εκχωρείται σε τίποτα. Μερικές φορές αρκεί να αλλάζει απλώς μία από τις συμβολοσειρές που περνάει ο δείκτης.

Ένα άλλο πράγμα είναι συναρτήσεις όπως η strlen() ή η strcmp() , οι οποίες δεν αλλάζουν παραμέτρους, αλλά καλούνται για χάρη του αποτελέσματος. Η συνάρτηση strcmp() συγκρίνει δύο συμβολοσειρές ορισμάτων γράμμα προς γράμμα (λεξικογραφικά) και επιστρέφει 0, -1 ή 1. Για παράδειγμα, καλώντας το strcmp("boy", "body") θα επιστρέψει 1 επειδή ο κωδικός του γράμματος «y» είναι μεγαλύτερος από το γράμμα «d». Η κλήση strcmp("body", "boy") θα επιστρέψει -1 επειδή το πρώτο επιχείρημα είναι λεξικογραφικά μικρότερο από το δεύτερο.

συνάρτηση strtok()

Με τη χρήση συναρτήσεις strtok() μπορείτε να χωρίσετε μια συμβολοσειρά σε ξεχωριστά μέρη (tokens). Η δήλωση αυτής της συνάρτησης μοιάζει με αυτό: char *strtok (char *, const char *) . Όταν η συνάρτηση καλείται για πρώτη φορά, η πρώτη παράμετρος είναι η συμβολοσειρά που πρέπει να διαχωριστεί. Η δεύτερη παράμετρος καθορίζει τη συμβολοσειρά διαχωρισμού. Σε επόμενες κλήσεις στη συνάρτηση για την ίδια συμβολοσειρά, η πρώτη παράμετρος πρέπει να είναι NULL, επειδή η συνάρτηση έχει ήδη «θυμηθεί» με τι λειτουργεί. Ας δούμε ένα παράδειγμα:

char str = "ένα, δύο, τρία, τέσσερα, πέντε" ; char * sp; sp = strtok (str, ", " ); ενώ (sp) ( βάζει (sp); sp = strtok (NULL, ", " ) ; )

Ως αποτέλεσμα της εκτέλεσης αυτού του κώδικα, οι ακόλουθες λέξεις εμφανίζονται στην οθόνη σε μια στήλη:

Ενα δύο τρία τέσσερα πέντε

Την πρώτη φορά που καλείται η strtok(), ένας δείκτης στον πρώτο χαρακτήρα του πίνακα και μια συμβολοσειρά οριοθέτη περνούν στη συνάρτηση. Μετά από αυτήν την κλήση, ο πίνακας str αλλάζει, παραμένει μόνο η λέξη "one" και η συνάρτηση επιστρέφει επίσης έναν δείκτη σε αυτήν τη λέξη, ο οποίος έχει εκχωρηθεί στο sp.

Παρόλο που χάσαμε τον υπόλοιπο πίνακα στη συνάρτηση κλήσης, ένας δείκτης προς τον υπόλοιπο πίνακα αποθηκεύεται μέσα στη strtok(). Όταν περάσει το NULL, η συνάρτηση "γνωρίζει" να λειτουργεί με αυτήν την "ουρά".

Αντιγραφή τμημάτων χορδών

Όταν χρειάζεται απλώς να συνδέσετε δύο συμβολοσειρές, το πρόβλημα λύνεται εύκολα καλώντας τη συνάρτηση strcat(), η οποία προσθέτει τη δεύτερη στο τέλος του πρώτου ορίσματος. Μια παρόμοια συνάρτηση, η strncat(), προσθέτει n χαρακτήρες της δεύτερης συμβολοσειράς στην πρώτη. Το n καθορίζεται ως η τρίτη παράμετρος.

Τι γίνεται αν η κατάσταση είναι πιο περίπλοκη; Για παράδειγμα, υπάρχουν δύο μη κενές γραμμές και πρέπει να συνδέσετε την αρχή της πρώτης και το τέλος της δεύτερης. Αυτό μπορεί να γίνει χρησιμοποιώντας τη συνάρτηση strcpy(), εάν μεταβιβάσετε αναφορές όχι στους πρώτους χαρακτήρες των γραμμών:

char s1[ 20 ] = "Peter Smith" , s2 = "Julia Roberts" ; strcpy (s1+ 5 , s2+ 5 ) ; βάζει (s1) ;

Σε αυτήν την περίπτωση, στην οθόνη θα εμφανιστεί το "Peter Roberts". Γιατί συνέβη; Ένας δείκτης στον έκτο χαρακτήρα της πρώτης γραμμής μεταβιβάστηκε στη συνάρτηση strcpy(). Αυτό οδήγησε στο γεγονός ότι κατά την αντιγραφή, οι χαρακτήρες αυτής της γραμμής αντικαθίστανται μόνο ξεκινώντας από την 6η, επειδή Η strcpy() δεν "γνωρίζει" τίποτα για προηγούμενους χαρακτήρες. Μόνο μέρος της συμβολοσειράς μεταβιβάζεται επίσης ως δεύτερο όρισμα, το οποίο αντιγράφεται στο πρώτο.

Πώς να εισάγετε μια γραμμή στη μέση μιας άλλης; Μπορείτε να λύσετε αυτό το πρόβλημα χρησιμοποιώντας μια τρίτη γραμμή "buffer", όπου μπορείτε πρώτα να αντιγράψετε την πρώτη γραμμή, μετά τη δεύτερη, σβήνοντας το τέλος της πρώτης και, στη συνέχεια, να προσθέσετε το τέλος της πρώτης. Αλλά μπορείτε επίσης να κάνετε αυτό:

char s1[ 20 ] = "ένα τρία" , s2[ 20 ] = "δύο" ; strcpy (s2+ 3 , s1+ 3 ) ; strcpy (s1+ 4 , s2) ; βάζει (s1) ;

Εδώ, πρώτα το τέλος της πρώτης αντιγράφεται στη δεύτερη γραμμή, με αποτέλεσμα "δύο τρία". Στη συνέχεια, η δεύτερη γραμμή αντιγράφεται στην πρώτη γραμμή, παρακάμπτοντας την αρχή της.

Περιγραφή ορισμένων λειτουργιών για εργασία με χορδές

Ασκηση
Ακολουθούν περιγραφές ορισμένων συναρτήσεων που εκτελούν λειτουργίες σε συμβολοσειρές. Σχεδιάστε και γράψτε μικρά προγράμματα για να δείξετε πώς λειτουργούν αυτές οι λειτουργίες.

  • char *strchr (const char *, int c) . Επιστρέφει έναν δείκτη στην πρώτη εμφάνιση του χαρακτήρα c στη συμβολοσειρά. Επιστρέφει NULL εάν δεν υπάρχει τέτοιος χαρακτήρας στη συμβολοσειρά.
  • char *strstr (const char *s2, const char *s1) . Επιστρέφει έναν δείκτη στην πρώτη εμφάνιση της συμβολοσειράς s1 στη συμβολοσειρά s2. Εάν δεν υπάρχουν αντιστοιχίες, επιστρέφει NULL.
  • char *strncpy (char *, const char *, size_t n) . Αντιγράφει n χαρακτήρες της δεύτερης γραμμής στην πρώτη.
  • size_t strspn (const char *, const char *) . Επιστρέφει το μήκος της αρχής της πρώτης συμβολοσειράς, η οποία περιλαμβάνει τους χαρακτήρες που αποτελούν τη δεύτερη συμβολοσειρά.

Περιγραφή

Η συνάρτηση strtok αναζητά διακριτικά στη συμβολοσειρά. Μια ακολουθία κλήσεων σε αυτή τη συνάρτηση χωρίζει τη συμβολοσειρά σε διακριτικά, τα οποία είναι ακολουθίες χαρακτήρων που χωρίζονται με χαρακτήρες οριοθέτησης.

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

Για να προσδιορίσει την αρχή ενός διακριτικού, η συνάρτηση καθορίζει πρώτα τους χαρακτήρες που δεν περιέχονται στη συμβολοσειρά delim, δηλαδή είναι χαρακτήρες οριοθέτησης. Και μετά ελέγχει την υπόλοιπη συμβολοσειρά χαρακτήρα προς χαρακτήρα μέχρι τον πρώτο χαρακτήρα οριοθέτησης, ο οποίος σηματοδοτεί το τέλος του διακριτικού.

Αυτό το τελικό διακριτικό αντικαθίσταται αυτόματα με έναν μηδενικό χαρακτήρα και το διακριτικό επιστρέφεται από τη συνάρτηση. Μετά από αυτό, οι επόμενες κλήσεις στη συνάρτηση strtok ξεκινούν με αυτόν τον μηδενικό χαρακτήρα.

Επιλογές:

  • σειρά
    Μια συμβολοσειρά για αναζήτηση λεξημάτων. Το περιεχόμενο αυτής της συμβολοσειράς θα αλλάξει, θα σπάσει σε μικρότερες συμβολοσειρές (tokens). Αυτή η παράμετρος μπορεί να περιέχειμηδενικός δείκτης, οπότε η συνάρτηση συνεχίζει τη σάρωση από το σημείο που σταμάτησε η προηγούμενη επιτυχημένη κλήση λειτουργίας.
  • delim
    Μια συμβολοσειρά που περιέχει οριοθέτες. Μπορούν να διαφέρουν από μια κλήση συνάρτησης σε μια άλλη κλήση λειτουργίας.

Επιστρεφόμενη αξία

Ένας δείκτης στο τελευταίο διακριτικό που βρέθηκε στη συμβολοσειρά.
Ένας μηδενικός δείκτης επιστρέφεται εάν δεν βρεθούν διακριτικά.

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

//παράδειγμα χρήσης της συνάρτησης strtok #include #περιλαμβάνω int main () ( char str = "Χαρακτηριστικά της εθνικής αλιείας - ταινία μεγάλου μήκους, κωμωδία."; std::cout<< "Разделение строки "" << str << "" на лексемы:n"; char * pch = strtok (str," ,.-"); // во втором параметре указаны разделитель (пробел, запятая, точка, тире) while (pch != NULL) // пока есть лексемы { std::cout << pch << "n"; pch = strtok (NULL, " ,.-"); } return 0; }


Μπλουζα