strtok 跳过多个定界符,如何让它只跳过一个

strtok skips more than one delimiter, how to make it skip only one

我目前正在为 nmea 句子开发一个解析器,通常是这样的:

"$GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62\r\n"

所以我创建了这个函数,它使用 strtok 使用逗号作为分隔符来解析它,并将每个数据字段存储在值数组中,重要的是每个数据字段都进入数组中的正确位置。

int split_string_by_comma (nmea_message_t * message_info, char ** values)
{
    int i = 0;
    char * p = strtok(message_info->data_field, MSG_DELIMITER);
    
    while (p != NULL)
    {
        values[i++] = p;
        p = strtok(NULL, MSG_DELIMITER);
    }
    return i;
}

问题是,nmea 语句跳过某些数据字段的情况并不少见,示例:

"$GPRMC,,A,,S,14507.36,E,000.0,,,,E*62\r\n"

在这种情况下,我的函数是无用的,因为我希望逗号之间的空数据字段被分配为 NULL 值,而不是被完全忽略。

有什么建议吗? 谢谢!

strsep 可能是您想要的:

The strsep() function was introduced as a replacement for strtok(3),
since the latter cannot handle empty fields.
However, strtok(3) conforms to C89/C99 and hence is more portable.

其语法不完全相同:

#include  <stdio.h>
#include  <string.h>

#define MSG_DELIMITER ","

void split_string_by_comma (char* msg)
{
    int i = 0;
    char * p = strsep(&msg, MSG_DELIMITER);

    while (p != NULL)
    {
        printf("%d - %s\n", ++i, p);
        p = strsep(&msg, MSG_DELIMITER);
    }    
}

int main(void)
{
    char good[] = "$GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62\r\n";
    char bad[] = "$GPRMC,,A,,S,14507.36,E,000.0,,,,E*62\r\n";

    split_string_by_comma(good);
    split_string_by_comma(bad);
    return 0;
}

:~/test/strsep$ ./a.out
1 - $GPRMC
2 - 081836
3 - A
4 - 3751.65
5 - S
6 - 14507.36
7 - E
8 - 000.0
9 - 360.0
10 - 130998
11 - 011.3
12 - E*62

1 - $GPRMC
2 -
3 - A
4 -
5 - S
6 - 14507.36
7 - E
8 - 000.0
9 -
10 -
11 -
12 - E*62