以逗号分隔的字符串的解析函数

时间:2016-02-02 10:02:14

标签: c string parsing arduino delimiter

假设我有一个像"cmd,param1,param2"这样的字符串。 String是Arduino字符串类型。 https://www.arduino.cc/en/Reference/String

我想提取用逗号分隔的每个子字符串。我已经成功编写了这样的特定案例的代码。这是代码;

String = str_data('cmd,param1,param2');
int firstCommaIndex = str_data.indexOf(',');
int secondCommaIndex = str_data.indexOf(',', firstCommaIndex+1);
String cmd = str_data.substring(0, firstCommaIndex);
String param1 = str_data.substring(firstCommaIndex+1, secondCommaIndex);
String param2 = str_data.substring(secondCommaIndex+1);

我的问题是有一个解决一般情况的功能。该字符串可以用任意数量的逗号分隔。我希望有一个看起来像这样的功能;

String parserCommaDelimited(String input_delimited_str, int nth_param_num)
{
    //implementation
}

假设input_delimited_str="cmd,param1,param2,param3,param4"

parserCommaDelimited(input_delimited_str, 1)返回"cmd"parserCommaDelimited(input_delimited_str, 5)会返回"param4"

3 个答案:

答案 0 :(得分:4)

以下是基本的CSV解析器:

void readCSVline(char *line);
char *readCSVfield(char *line, char *buf);
void readCSVdemo(void)
{
    char line[]= "0,,10004,10004,\"Albany Hwy After Galliers Av\",\"\",-32.13649428,116.0176090070,3";
    readCSVline(line);

}
/* readCSVline is where you put your "intelligence" about fields to read
 * and what to do with them
 */
void readCSVline(char *line)
{
    char field1[80], *lineptr=line;
    int nfields=0;

    while (*lineptr) {
        lineptr= readCSVfield(lineptr, field1);
        printf("%s\n", field1);
        nfields++;
    }
    printf("%d fields read.\n", nfields);
}
/* readCSVfield reads a field from a CSV line until the next comma or end-of-line.
 * It returns where the reading stopped.
 */
char *readCSVfield(char *line, char *buf)
{
    int instr= FALSE;   // track whether we are in a string
    char *cptr= line;

    while (*cptr)
    {
        if (instr) {
            if (*cptr=='"') {
                char cc= *++cptr;
                if (cc=='"')        // escaped double quote
                    *buf++ = '"';
                else {
                    *buf='\0';
                    cptr--;
                    instr= FALSE;
                }
            }
            else *buf++ = *cptr;
        }
        else switch (*cptr) {
        case '"': instr= TRUE; break;
        case ',': cptr++; *buf= '\0'; return(cptr);
        case ' ': case '\t': case '\n': case '\r': break;
        default: *buf++ = *cptr;
        }
        cptr++;
    }
    *buf= '\0';
    return(cptr);
}

答案 1 :(得分:2)

您可以按照以下方式拆分字符串并获得您想要的任何内容。

int split(char *result[], const char *str, char tok) {
    char buff[1024]; // it's better to use length of str instead of 1024
    int idx = 0;
    int len = 0;
    int ent_cnt = 0;
    int st = 0;

    // parse string
    while(1) {
        char ch = str[len++]; // need checking len to avoid overflow

        // end of string?
        if (ch == '\0')
            break;

        switch(st) {
            case 0: {
                if (ch == tok)
                    st++;
                else
                    buff[idx++] = ch;

                break;
            }

            case 1: {
                if (idx) {
                    char *entry = malloc(idx + 1);
                    int i;

                    for (i = 0; i < idx; i++)
                        entry[i] = buff[i];

                    entry[i] = '\0';
                    result[ent_cnt++] = entry;
                    idx = 0;
                }

                // normal char?
                if (ch != tok)
                    buff[idx++] = ch;

                st--;
                break;
            }

            default:
                break;
        }
    }

    // process last part if any
    if (idx) {
        char *entry = malloc(idx + 1);

        int i = 0; 
        for (i = 0; i < idx; i++)
            entry[i] = buff[i];

        entry[i] = '\0';
        result[ent_cnt++] = entry;
    }

    return ent_cnt;
}

int main(int argc, char *argv[]) {
    char *result[10];
    int cnt = split(result, "s,this,is,a,test,", ',');
    int i = 0;

    for (i = 0; i < cnt; i++) {
        printf("%s\n", result[i]);
    }

    if (cnt != 5) {
        printf("Fail!\n");
    }

    return 0;
}

答案 2 :(得分:1)

尝试使用split,在c ++中是strtok:

variable = strtok(variable,&#34; delimiter&#34;); 将字符串转换为数组,用c ++我不知道,我用php&amp; amp;编程javascript,但你可以观看:

http://www.cplusplus.com/reference/cstring/strtok/

我希望它可以帮到你!