使用分隔符的Strtok行为

3
以下是代码片段。
#define TABLE_DELIMITER "::"
int parse_n_store ( char *line )
{

        int i = 0;
        char *p = NULL;
        CPTR sensor_number = NULL , event_catagory = NULL, sensor_type = NULL, event_state= NULL, assertion = NULL, message_number = NULL, short_text = NULL;

        for (p = strtok(line,TABLE_DELIMITER); p != NULL; p = strtok(NULL, TABLE_DELIMITER), i++ )
        {
                if ( i == 0 )
                        sensor_number=p;
                else if ( i == 1 )
                        sensor_type = p;
                else if ( i == 2 )
                        event_catagory = p;
                else if ( i == 3 )
                        event_state = p;
                else if ( i == 4 )
                        assertion = p;
                else if ( i == 5 )
                        message_number = p;
                else if ( i == 6 )
                        short_text = p;
        }

        printf ("%s %s %s %s %s %s %s\n", sensor_number, event_catagory, sensor_type, event_state, assertion, message_number, short_text);
}

这个工作很好。但是,当“line”参数为“Front Board Memory status:Correctable ECC / other correctable memory error detected; sensor (70, Memory)”时,
输出将为
70 SENSOR_SPECIFIC MEMORY STATE_00 True 8543 Front Board Memory status
其中short_text变量仅包含“Front Board Memory status”,而不是“Front Board Memory status: Correctable ECC / other correctable memory error detected; sensor (70, Memory)”。
为什么strtok将单个冒号视为分隔符?有谁能解决这个问题。

1
strtok函数的第二个参数中的每个字符都是一个分隔符。 - Spikatrix
2个回答

6
为什么strtok将单个冒号视为分隔符?
因为这是在标准(C11)中规定的:
7.24.5.8 strtok函数
[...]
2. 对strtok函数的一系列调用将指向s1的字符串分解成一系列标记,每个标记都由s2指向的字符串中的一个字符分隔。序列中的第一个调用具有非空的第一个参数;序列中的后续调用具有空的第一个参数。s2所指的分隔符字符串可能会在不同的调用中不同。

1
你可以尝试使用strstr来迭代字符串,因为它可以查找子字符串。
你可以定义(请注意未经测试):
char *strmtok(char *s, char *delim) {
    static char *current = NULL;
    char *ix, *cr;

    if (s != NULL) { 
        current = s;
    }
    ix = strstr(current, delim);
    if (ix == NULL) return NULL;
    cr = current;
    current = ix + strlen(delim);
    *ix = '\0';
    return cr;
}

使用它来替换原始的strtok。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接