簡體   English   中英

C strtok,如果我想保留定界符怎么辦?

[英]C strtok, what if I want to keep the delimiter?

我正在嘗試拆分以下類型的行:

GM 1 2 3 ! this is a comment

分隔注釋部分。 有幾種可能的注釋定界符,!,'和#。 strtok是很明顯的解決方案:

card->card_str = strtok(line_buf, "!'#");

生產GM 1 2 3this is a comment 但是,對於這個角色,我需要在第二個字符串中保留定界符,因此在這種情況下! this is a comment ! this is a comment 是否有捷徑可尋?

strtok很少是解析作業的正確工具,因為它有許多怪癖和副作用。

為了您的目標,您可以使用strcspn()

void parse_input_line(const char *line) {
    size_t len = strcspn(line, "!'#");
    char *p = malloc(len + 1);
    if (p != NULL) {
        memcpy(p, line, len);
        p[len] = '\0';
        card->card_str = p;
        card->card_comment = p[len] ? strdup(p + len) : NULL;
    }
}

或者,您可以使用strpbrk

void parse_input_line(const char *line) {
    const char *sep = strpbrk(line, "!'#");
    if (sep == NULL) {
        // no comment
        card->card_str = strdup(line);
        card->card_comment = NULL;
    } else {
        size_t len = sep - line;
        char *p = malloc(len + 1);
        if (p != NULL) {
            memcpy(p, line, len);
            p[len] = '\0';
            card->card_str = p;
            card->card_comment = strdup(sep);
        }
    }   
}

您可以使用strndup使代碼更具可讀性:

void parse_input_line(const char *line) {
    size_t len = strcspn(line, "!'#");
    if (p[len] == '\0') {
        /* no comment */
        card->card_str = strdup(line);
        card->card_comment = NULL;
    } else {
        card->card_str = strndup(line, len);
        card->card_comment = strdup(p + len);
    }
}

strndup可能並非在所有系統上都可用,這是一個簡單的實現:

size_t strnlen(const char *s, size_t n) {
    size_t len;
    for (len = 0; len < n; len++) {
        if (s[len] == '\0')
            break;
    }
    return len;
}

char *strndup(const char *s, size_t n) {
    size_t len = strnlen(s, n);
    char *p = malloc(len + 1);
    if (p != NULL) {
        memcpy(p, s, len);
        p[len] = '\0';
    }
    return p;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM