strtok කාර්යයන්. C හි strtok ශ්‍රිතය ක්‍රියා කරන්නේ කෙසේද? උදාහරණය: වැඩසටහන් මූල කේතය

වෙනත් අන්වර්ථ නාමයන්

strtok

සමාලෝචනය

#ඇතුළත්

char *strok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim,char**saveptr);

glibc සඳහා දේපල පරීක්ෂා කිරීමේ සාර්ව සඳහා අවශ්‍යතා (බලන්න විශේෂාංග_පරීක්ෂණ_මැක්‍රෝස්(7)):

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

විස්තර

කාර්යය strtok() තන්තුවක් ශුන්‍ය හෝ ඊට වැඩි හිස් නොවන ටෝකන අනුපිළිවෙලකට බෙදයි. පළමු ඇමතුමේදී strtok() විශ්ලේෂණය කළ යුතු තන්තුව තර්කයේ සඳහන් කළ යුතුය str. එකම තන්තුව විග්‍රහ කරන සෑම පසු ඇමතුමකදීම, අගය str NULL විය යුතුය.

තර්කයේ delimවිශ්ලේෂණය කරන ලද තන්තුවෙහි ටෝකන් බෙදුම්කරුවන් ලෙස සලකනු ලබන බයිට් කට්ටලයක් නියම කර ඇත. අමතන්නාට විවිධ රේඛා සඳහන් කළ හැක delimඑකම තන්තුව විග්‍රහ කරන විට පසු ඇමතුම් වලදී.

සෑම ඇමතුමක්ම strtok() ඊළඟ ටෝකනය අඩංගු null-terminated string වෙත දර්ශකයක් ආපසු ලබා දෙයි. මෙම පේළියේ පරිසීමක බයිටයක් ඇතුළත් නොවේ. තවත් ටෝකන නොමැති නම්, එසේ නම් strtok() NULL ආපසු ලබා දෙයි.

ඇමතුම් අනුපිළිවෙල strtok(), තනි තන්තුවක් මත ක්‍රියාත්මක වන අතර, ඊළඟ ටෝකනය සඳහා සෙවීම ආරම්භ වන ලක්ෂ්‍යය නියම කරන දර්ශකයක් පවත්වාගෙන යයි. පළමු ඇමතුම strtok() මෙම දර්ශකයට තන්තුවේ පළමු බයිටයට යොමුවක් පවරයි. ඊළඟ ටෝකනයේ ආරම්භය තීරණය වන්නේ ඉදිරියට සෙවීමෙන් strඊළඟ බයිටය පරිසීමකයක් නොවේ. බයිටයක් හමු වුවහොත් එය ඊළඟ ටෝකනයේ ආරම්භය ලෙස ගනු ලැබේ. එවැනි බයිටයක් සොයාගත නොහැකි නම්, තවත් ටෝකන නොමැත සහ strtok() NULL ආපසු ලබා දෙයි (හිස් හෝ සීමා කළ තන්තුවක් සඳහා, NULL පළමු වරට එය හැඳින්වූ විට ආපසු ලබා දෙනු ඇත strtok()).

පරිසීමක බයිටයක් හෝ පසුපසින් ඇති ශුන්‍ය බයිටයක් ("\0") සොයා ගන්නා තෙක් එක් එක් ටෝකනයක අවසානය ඉදිරි සෙවුමක් මගින් සොයා ගනු ලැබේ. පරිසීමක බයිටයක් හමු වුවහොත්, එය වත්මන් ටෝකනය අවසන් කිරීමට ශුන්‍ය බයිටයකින් ප්‍රතිස්ථාපනය වේ, සහ strtok() ඊළඟ බයිටයට දර්ශකයක් ගබඩා කරයි; ඊළඟ ටෝකනය සෙවීමේදී මෙම දර්ශකය ආරම්භක ලක්ෂ්‍යයක් ලෙස භාවිතා කරනු ඇත. මේ අවස්ථාවේ දී strtok() සොයාගත් ටෝකනයේ ආරම්භයට දර්ශකයක් ආපසු ලබා දෙයි.

ඉහත විස්තරයෙන්, ස්කෑන් කරන ලද පේළියේ එක දිගට පරිසීමක බයිට් දෙකක හෝ වැඩි ගණනක අනුපිළිවෙලක් තනි පරිසීමකයක් ලෙස සලකනු ලබන අතර, තන්තුවේ ආරම්භයේ හෝ අවසානයේ ඇති පරිසීමක බයිට් නොසලකා හරිනු ලැබේ. වෙනත් වචන වලින් කිවහොත්, ටෝකන ආපසු පැමිණියේය strtok() - සෑම විටම හිස් නොවන නූල්. එනම්, උදාහරණයක් ලෙස, රේඛාවක් තිබේ නම් " aaa;;bb,", පසුව පසුව ඇමතුම් strtok() දී ඇති රේඛා බෙදුම්කරුවන් සමඟ " ;, "තත් ආපසු දෙන්නම්" aaa" සහ " bbb"ඉන්පසු null pointer එකක්.

කාර්යය strtok_r() යනු නැවත ඇතුල් කරන ලද අනුවාදයයි strtok(). තර්කය saveptrයනු විචල්‍යයකට දර්ශකයකි char *අභ්යන්තරව භාවිතා කරන strtok_r() එකම තන්තුව විග්‍රහ කිරීමේදී පසුව එන ඇමතුම් අතර සන්දර්භය සැලකිල්ලට ගැනීමට.

පළමු ඇමතුමේදී strtok_r() අර්ථය strවිග්‍රහ කර ඇති තන්තුව සහ අගය වෙත යොමු කළ යුතුය saveptrනොසලකා හැර ඇත. පසු ඇමතුම් වල අගය str NULL සහ අගය විය යුතුය saveptrපෙර ඇමතුමේ සිට වෙනස් නොවිය යුතුය.

විවිධ පේළි බහු ධාවන හරහා එකවර විශ්ලේෂණය කළ හැක strtok_r() විවිධ තර්ක සමඟ saveptr.

ආපසු වටිනාකම

කාර්යයන් strtok() සහ strtok_r() තවත් ටෝකන නොමැති නම් ඊළඟ ටෝකනයට හෝ NULL වෙත දර්ශකයක් ආපසු එවන්න.

ගුණාංග

මෙම කොටසේ නියමයන් පිළිබඳ විස්තරයක් සඳහා, බලන්න ගුණාංග(7).
අතුරුමුහුණත ගුණාංගය අර්ථය
strtok() නූල් වල හානිකර බවඅනාරක්ෂිත (MT-Unsafe race: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.

දෝෂ

මෙම විශේෂාංග ප්‍රවේශමෙන් භාවිතා කරන්න. කරුණාකර සටහන් කර ගන්න: * මෙම ශ්‍රිතයන් ඔවුන්ගේ පළමු තර්කය වෙනස් කරයි. * මෙම කාර්යයන් නියත නූල් සමඟ භාවිතා කළ නොහැක. * බෙදුම්කරු බයිටයේ අනන්‍යතාවය නැති වී යයි. * කාර්යය විශ්ලේෂණය කරන විට strtok() ස්ථිතික බෆරයක් භාවිතා කරන අතර එබැවින් නූල් ආරක්ෂිත නොවේ. භාවිත strtok_r() මේ අවස්ථාවේ දී.

උදාහරණයක්

පහත වැඩසටහන ඇමතීමට nested loops භාවිතා කරයි strtok_r() තන්තුවක් එහි සංඝටක ටෝකන් වලට බෙදීමට. පළමු පරාමිතිය තුළ විධාන රේඛාවවිශ්ලේෂණය කළ යුතු තන්තුව නියම කර ඇත. දෙවන පරාමිතිය බෙදුම්කරු බයිට් (ය) නියම කරයි, එය තන්තුව “සංයුක්ත” ටෝකනවලට බෙදීමට භාවිතා කරයි. තුන්වන පරාමිතිය "සංයුක්ත" ටෝකන උප ටෝකනවලට වෙන් කිරීමට භාවිතා කරන බෙදුම්කරු බයිට් (ය) නියම කරයි.

වැඩසටහන් ප්‍රතිදානයේ උදාහරණය:

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

වැඩසටහන් මූල කේතය

#ඇතුළත් #ඇතුළත් #ඇතුළත් 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_FAILURE); ) සඳහා (j = 1, str1 = argv; ; j++, str1 = NULL) (ටෝකනය = strtok_r(str1, argv, &saveptr1); නම් (ටෝකනය = = NULL) බිඳීම; printf ("%d: %s\n", j, ටෝකනය); (str2 = ටෝකනය; ; str2 = NULL) සඳහා (උප ටෝකනය = strtok_r(str2, argv, &saveptr2); නම් (උප ටෝකනය == NULL) බිඳීම; printf(" --> %s\n", subtoken); ) ) පිටවීම(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() සඳහා වන පළමු තර්කය තන්තුවකට යොමු කරන්නේ නම්, අභ්‍යන්තර දර්ශකය එම තන්තුවේ ආරම්භයට සකසා ඇත. පළමු තර්කය NULL නම්, strtok() පෙර පියවරේදී ඉගෙන ගත් ස්ථානයේ සිට පෙර තන්තුව සැකසීම දිගටම කරගෙන යන අතර ඊළඟ ටෝකනය ලබා ගන්නා විට අභ්‍යන්තර දර්ශකය ඉදිරියට ගෙන යයි. මේ අනුව, strtok() ශ්‍රිතය මුළු තන්තුවම "ගමන් කරයි". ශ්‍රිතයට ලැබෙන පළමු සහ පසුව ලැබෙන ඇමතුම් වලදී පරිසීමක තන්තුව වෙනස් වන ආකාරය ද සැලකිල්ලට ගන්න. එක් එක් ඇමතුම සඳහා පරිසීමක වෙනස් ලෙස අර්ථ දැක්විය හැක.

#ඇතුළත් char *strok(char * str1, const char * str2);

strtok() ශ්‍රිතය පරාමිතිය මගින් ආමන්ත්‍රණය කරන ලද තන්තුවෙහි ඊළඟ ටෝකනය වෙත දර්ශකයක් ලබා දෙයි. str1. පරාමිතිය මගින් ආමන්ත්‍රණය කරන ලද තන්තුව සාදන අක්ෂර str2, ටෝකනයක් නිර්වචනය කරන පරිසීමක වේ. ආපසු යාමට ටෝකනයක් නොමැති නම්, ශුන්‍ය දර්ශකයක් ආපසු ලබා දෙනු ලැබේ.

C99 අනුවාදයේ පරාමිතීන් වෙත str1සහ str2සීමා සහිත සුදුසුකම් අදාළ වේ.

තන්තුවක් ටෝකනවලට බෙදීමට, ඔබ පළමු වරට strtok(), පරාමිතිය අමතන්න str1මෙම පේළියේ ආරම්භය වෙත යොමු කළ යුතුය. පරාමිතියක් ලෙස ශ්‍රිතයට පසුව ලැබෙන ඇමතුම් වලදී str1ඔබ null pointer එකක් භාවිතා කළ යුතුයි. මේ ආකාරයට, මුළු තන්තුවම ටෝකන් වලට බෙදී ඇත.

strtok() ශ්‍රිතයට ලැබෙන සෑම ඇමතුමකටම වෙනස් පරිසීමක කට්ටලයක් භාවිතා කළ හැක.

උදාහරණයක්

මෙම වැඩසටහන මඟින් “තණකොළ කොළ පාටයි, හිරු බබළයි” යන තන්තුව අවකාශයන් සහ කොමාව මගින් වෙන් කරන ලද සංකේත බවට බිඳ දමයි. ප්රතිඵලය වනු ඇත

තණකොළ|කොළ පැහැයට හැරේ|හිරු|දීප්ති #ඇතුළත් වේ #ඇතුළත් int main(void) ( char *p; p = strtok ("තණකොළ කොළ පාටයි, හිරු බබළයි", ""); printf(p); do (p = strtok("\0", ", ") ; if(p ) printf("|%s", p); ) while(p); ආපසු 0;)

වාක්‍ය ඛණ්ඩ:

#ඇතුළත්
char *strtok(char *str, const char *sep);

තර්ක:

str - බෙදිය යුතු තන්තුවට දර්ශකය.
sep - පරිසීමක අක්ෂර කට්ටලයක් අඩංගු තන්තුවකට දර්ශකය.

ප්‍රතිලාභ අගය:

NULL - string str එක කොටස් වලට බෙදිය නොහැකි නම්.
තන්තුවෙහි තෝරාගත් කොටසෙහි පළමු අක්ෂරයට දර්ශකයක්.

විස්තර:

strtok ශ්‍රිතය මඟින් str තර්කය මඟින් පෙන්වා දෙන ලද තන්තුවේ ඊළඟ කොටස තෝරා ගනියි, sep තර්කය මඟින් පෙන්වා දෙන ලද තන්තුවෙහි දක්වා ඇති පරිසීමක අක්ෂරවලින් එකකින් වෙන් කරනු ලැබේ. strtok ශ්‍රිතයට අඛණ්ඩ ඇමතුම් ප්‍රතිඵලයක් ලෙස string str කොටස් වලට (ටෝකන) බෙදී යයි.

“strtok ශ්‍රිතයට ලැබෙන පළමු ඇමතුමෙන් බෙදිය යුතු තන්තුවේ ආරම්භය (str) සහ බෙදුම්කරුවන් (sep) අඩංගු තන්තුවේ ආරම්භය සඳහන් කරයි. strtok ශ්‍රිතය ආරම්භ වන්නේ string string හි අක්ෂර එකින් එක බැලීමෙන් සහ සීමා කළ string sep හි අඩංගු නොවන අක්ෂරයක් සෙවීමෙනි. string string string sep හි ඇතුළත් නොවූ අක්ෂරයක් සොයා ගැනීමට පෙර පේළියේ අන්තයේ අක්ෂරය හමු වුවහොත්, string str කොටස් වලට බෙදිය නොහැකි අතර ශුන්‍ය දර්ශකයක් (NULL) ආපසු ලබා දෙනු ඇත. එවැනි චරිතයක් හමු වුවහොත්, එය string string හි පළමු කොටසේ ආරම්භය ලෙස සැලකේ."

මීලඟට, strtok ශ්‍රිතය බෙදුම්කරු සොයයි, එනම්, sep string හි ඇතුළත් අක්ෂරය. එවැනි අක්ෂරයක් සොයාගත නොහැකි නම්, string str එක කොටසකින් සමන්විත ලෙස සලකනු ලබන අතර string str හි පසුව බෙදීම් ශුන්‍ය දර්ශකයක් ලබා දෙනු ඇත. එවැනි සංකේතයක් හමු වුවහොත්. එවිට එය ශුන්‍ය අක්ෂරයකින් (අන්ත-රේඛා අක්ෂර) ප්‍රතිස්ථාපනය වේ. ඊළඟට, strtok ශ්‍රිතය වත්මන් ස්ථානය මතක තබා ගනී (තට්ටුවේ ඊළඟ කොටස සෙවීම ආරම්භ වන අක්ෂරයට දර්ශකයක්) සහ තන්තුවේ පළමු තෝරාගත් කොටසේ ආරම්භයට දර්ශකයක් ආපසු ලබා දෙයි.

strtok ශ්‍රිතය ශුන්‍ය නොවන දර්ශකයක් ආපසු ලබා දුන්නේ නම්, ඔබට string str කැබලිවලට බෙදීම දිගටම කරගෙන යා හැක. තන්තුව බෙදීම දිගටම කරගෙන යාමට, strtok ශ්‍රිතය නැවත කැඳවනු ලැබේ, නමුත් බෙදිය යුතු තන්තුවට දර්ශකයක් වෙනුවට, NULL පළමු වර්ධකය ලෙස දක්වා ඇත. මෙම අවස්ථාවේදී, strtok ශ්‍රිතය මතක තබා ගත් ලිපිනයෙන් බෙදීම දිගටම සිදු වේ. කොටස් කිරීමේ ඇල්ගොරිතම එලෙසම පවතිනු ඇත.

උදාහරණයක්:

උදාහරණයේ, "test1/test2/test3/test4" තන්තුව strtok ශ්‍රිතය භාවිතා කරමින් "/" පරිසීමකය භාවිතයෙන් කොටස් වලට බෙදා ඇත. බෙදීමේ ප්රතිඵලය කොන්සෝලය වෙත ප්රතිදානය වේ.

ප්‍රතිඵලය:

කොන්සෝල ප්‍රතිදානය:





ඉහල