strtok และการแยกโทเคน
แยกสตริง
strtok และการแยกโทเคน เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
การแบ่งเป็นโทเคนคืออะไร
การแบ่งเป็นโทเคน หมายถึงการแยกสตริงออกเป็นส่วนย่อย ๆ (โทเคน) โดยมีอักขระตัวคั่นแบ่งระหว่างส่วน
ตัวอย่างเช่น การแยก "a,b,c" ด้วยเครื่องหมายจุลภาคจะได้โทเคน a, b และ c ภาษา C มี strtok สำหรับงานนี้
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "a,b,c";
char *token = strtok(text, ",");
printf("First token: %s\n", token);
return 0;
}รูปแบบการประกาศ strtok
char *strtok(char *str, const char *delim);
ในการเรียกครั้งแรก ให้ส่งสตริงเข้าไป ส่วนการเรียกครั้งถัดไปให้ส่ง NULL เพื่อให้ทำงานต่อจากตำแหน่งเดิม ฟังก์ชันจะส่งกลับโทเคนถัดไป หรือ NULL เมื่อดำเนินการเสร็จแล้ว
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "red green blue";
char *tok = strtok(text, " ");
while (tok != NULL) {
printf("%s\n", tok);
tok = strtok(NULL, " ");
}
return 0;
}strtok แก้ไขสตริง
ข้อสำคัญ: strtok เปลี่ยนแปลงสตริงต้นฉบับ โดยแทนที่ตัวคั่นแต่ละตัวด้วย '\0' และส่งกลับตัวชี้ที่ชี้เข้าไปในบัฟเฟอร์เดียวกัน
ดังนั้นคุณจึงไม่สามารถแบ่งสตริงค่าคงที่อย่าง "a,b" เป็นโทเคนได้ เพราะสตริงนี้อ่านได้อย่างเดียว
#include <stdio.h>
#include <string.h>
int main(void) {
char data[] = "x:y:z";
strtok(data, ":");
printf("data[1] is now: %d (the null byte)\n", data[1]);
return 0;
}สร้างสำเนาที่เขียนได้
เนื่องจาก strtok ทำลายข้อมูลนำเข้าของตนเอง ให้คัดลอกสตริงก่อนหากคุณต้องใช้ต้นฉบับในภายหลัง
ใช้อาร์เรย์ char ภายในฟังก์ชัน หรือใช้ strcpy คัดลอกลงบัฟเฟอร์
#include <stdio.h>
#include <string.h>
int main(void) {
const char *original = "one-two-three";
char copy[64];
strcpy(copy, original);
char *tok = strtok(copy, "-");
while (tok) {
printf("%s\n", tok);
tok = strtok(NULL, "-");
}
printf("Original intact: %s\n", original);
return 0;
}ตัวคั่นหลายตัว
อาร์กิวเมนต์ delim คือชุดของอักขระ ไม่ใช่ลำดับอักขระ อักขระใด ๆ ในชุดจะทำหน้าที่เป็นตัวคั่น
ดังนั้น " ,;" จะแยกด้วยช่องว่าง เครื่องหมายจุลภาค และอัฒภาคพร้อมกัน
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "a,b;c d";
char *tok = strtok(text, ",; ");
while (tok) {
printf("[%s]\n", tok);
tok = strtok(NULL, ",; ");
}
return 0;
}ตัวคั่นที่อยู่ติดกัน
strtok ถือว่าตัวคั่นที่เรียงต่อกันหลายตัวเป็นตัวคั่นเดียว และข้ามโทเคนว่าง
ดังนั้น "a,,b" จะให้เพียง a และ b ไม่ได้ให้โทเคนว่างตรงกลาง โปรดคำนึงถึงเรื่องนี้เมื่อแยกวิเคราะห์ CSV ซึ่งช่องข้อมูลว่างอาจมีความหมาย
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "a,,b";
char *tok = strtok(text, ",");
while (tok) {
printf("token: %s\n", tok);
tok = strtok(NULL, ",");
}
return 0;
}การนับโทเคน
งานที่พบบ่อยคือการนับว่าสตริงมีโทเคนกี่รายการ ให้เพิ่มค่าตัวนับภายในลูป
#include <stdio.h>
#include <string.h>
int main(void) {
char sentence[] = "the quick brown fox";
int count = 0;
char *tok = strtok(sentence, " ");
while (tok) {
count++;
tok = strtok(NULL, " ");
}
printf("Word count: %d\n", count);
return 0;
}strtok เก็บสถานะที่ซ่อนอยู่
strtok เก็บตำแหน่งของตนไว้ในตัวแปรภายในแบบ static นี่คือเหตุผลที่ NULL ทำให้ทำงานต่อกับสตริงก่อนหน้า
ข้อเสียคือฟังก์ชันนี้ไม่รองรับการเรียกซ้อนอย่างปลอดภัยและไม่ปลอดภัยสำหรับการทำงานหลายเธรด คุณไม่สามารถแบ่งสตริงสองชุดเป็นโทเคนพร้อมกันได้
#include <stdio.h>
#include <string.h>
int main(void) {
char a[] = "1 2";
char *t = strtok(a, " ");
printf("%s\n", t);
t = strtok(NULL, " ");
printf("%s\n", t);
return 0;
}การจัดเก็บโทเคน
หากต้องการใช้โทเคนหลังจากแยกแล้ว ให้เก็บตัวชี้ที่ส่งกลับไว้ในอาร์เรย์ ตัวชี้เหล่านี้ชี้เข้าไปในบัฟเฟอร์ต้นทางที่ถูกแก้ไขแล้ว ซึ่งต้องคงอยู่ตลอดการใช้งาน
#include <stdio.h>
#include <string.h>
int main(void) {
char csv[] = "name,age,city";
char *fields[10];
int n = 0;
char *tok = strtok(csv, ",");
while (tok && n < 10) {
fields[n++] = tok;
tok = strtok(NULL, ",");
}
for (int i = 0; i < n; i++)
printf("Field %d: %s\n", i, fields[i]);
return 0;
}ทางเลือกที่รองรับการเรียกซ้อน
POSIX มี strtok_r ซึ่งรับ char **saveptr ที่ระบุอย่างชัดเจนแทนสถานะที่ซ่อนอยู่ ทำให้ปลอดภัยเมื่อนำไปเรียกซ้อนและใช้ข้ามเธรด
สำหรับภาษา C มาตรฐานที่พกพาได้ strtok ธรรมดาเพียงพอสำหรับการแยกวิเคราะห์แบบผ่านครั้งเดียว
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "p:q:r";
char *save;
char *tok = strtok_r(text, ":", &save);
while (tok) {
printf("%s\n", tok);
tok = strtok_r(NULL, ":", &save);
}
return 0;
}ภาคปฏิบัติ: แยกเส้นทาง
การแบ่งเป็นโทเคนมีประโยชน์มากเมื่อแยกวิเคราะห์ข้อความที่มีโครงสร้าง เช่น เส้นทางไฟล์ การแยกด้วย / จะแสดงองค์ประกอบแต่ละส่วนของเส้นทาง
#include <stdio.h>
#include <string.h>
int main(void) {
char path[] = "usr/local/bin";
char *part = strtok(path, "/");
while (part) {
printf("-> %s\n", part);
part = strtok(NULL, "/");
}
return 0;
}ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับการทำงานของ strtok
สรุปทบทวน
คุณได้เรียนรู้การแยกสตริงด้วย strtok:
- การเรียกครั้งแรกใช้สตริง ส่วนการเรียกครั้งต่อไปใช้ NULL
- ฟังก์ชันนี้แก้ไขข้อมูลนำเข้า โดยแทนที่ตัวคั่นด้วย
'\0'— ให้คัดลอกสตริงที่อ่านได้อย่างเดียวก่อน - อาร์กิวเมนต์ตัวคั่นเป็นชุด และตัวคั่นที่อยู่ติดกันจะถูกรวมเป็นตัวเดียว
- ฟังก์ชันใช้สถานะแบบ static และไม่ปลอดภัยสำหรับการทำงานหลายเธรด ให้ใช้
strtok_rเมื่อต้องการ
คำถามที่พบบ่อย
บทเรียน “strtok และการแยกโทเคน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “strtok และการแยกโทเคน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “strtok และการแยกโทเคน”
แยกสตริง คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “strtok และการแยกโทเคน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม
ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- strlen, strcpy, strcat
- strcmp และการเปรียบเทียบ
- strtok และการแยกโทเคน
- memcpy และ memset