0Pricing
C Academy · บทเรียน

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. strlen, strcpy, strcat
  2. strcmp และการเปรียบเทียบ
  3. strtok และการแยกโทเคน
  4. memcpy และ memset
← กลับไปที่ C Academy