【问题标题】:How to use strtok to get tokens within tokens?如何使用 strtok 获取令牌中的令牌?
【发布时间】:2020-08-23 07:40:07
【问题描述】:

我正在尝试从文件的每一行中分离标记并打印它们。我使用的分隔符是“,”。但是,某些行的最后一个字符串在字符串中具有带有“,”的标记。如何获取带有“,”的整个字符串?

char *buff = (char*)malloc(sizeof(char)*256);
char *tmp;

while (fgets(buff, 256, FILENAME) != NULL) {
    tmp = strtok(buff, ",");
    printf("%s\n",tmp);

    tmp = strtok(NULL, ",");
    printf("%s\n",tmp);

    tmp = strtok(NULL, ",");
    printf("%s\n",tmp);
    
}

输入文件中的行如下所示:

This,is,a
Code,in,"c,language"
rat, mouse, "rat, mouse"

我正在尝试这样的输出:

This
is
a
Code
in
c, language
rat
mouse
rat, mouse

【问题讨论】:

  • 要标记的字符串是否需要双引号?这有助于找到解决方案。
  • 不,只需要去掉每行最后一个标记中可能存在的双引号
  • 逐个字符遍历字符串...当您找到逗号时,逗号之前的内容是标记;当您找到报价时,开始在报价内进行子搜索,直到找到匹配的报价。
  • @ReajuddinRabbi 写一个正确的解析器来正确解析"strtok在这里是错误的方式。
  • Code,in,"c,language" 导致c, languageclanguage 之间的逗号从何而来?

标签: c string file strtok


【解决方案1】:

因为星期天的空闲时间是进行一些简单编码的好时机,所以这是我在短时间内编写的解析器。它不解析转义序列并且几乎没有错误处理,但可以帮助您入门。

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

void parse(FILE *file) {
    int c;
    // keep track if we are in quotes or not
    bool inquote = false;
    // keep track if the field started or not
    bool infield = false;
    
    while ((c = fgetc(file)) != EOF) {

        if (!infield) {
            // ignore leading spaces before fields
            if (c == ' ') continue;
            infield = true;
        }

        switch(c) {
        case '"':
            inquote = !inquote;
            continue;
        case ',':
            // if comma is in quotes, just print it
            if (inquote) break;
            // fallthrough
        case '\n':
            // comma or newline are field separators
            printf("\n");
            infield = false;
            continue;
        }
        // output the character
        printf("%c", c);
    }
}

int main() {
    parse(stdin);
    return 0;
}

it outputs on godbolt:

This
is
a
Code
in
c,language
rat
mouse
rat, mouse

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-05
    • 2020-02-26
    • 2021-08-19
    • 2015-07-19
    • 2021-01-29
    • 2018-11-26
    • 2013-09-05
    相关资源
    最近更新 更多