Как сделать парсер токена в C? - PullRequest
2 голосов
/ 29 марта 2012

Я видел файлы "config" (да, текстовые файлы) для различных консольных приложений, которые выглядят следующим образом

<token> <value>

Как мне разобрать такую ​​вещь в C, где может быть строкой, буквой или даже целым числом / float / double?

Я прочитал этот вопрос " Как мне разобрать токен из строки в C? ", где в основном рекомендуется использовать strtok, но также и то, что он не поточнобезопасен, и я планирую создание нескольких потоков (при условии, что я могу завершить свое приложение)

P.S Вот пример токена и значения

user username123
pass 123456

Ах, я забыл сложную часть. Я также должен уметь анализировать токен, который имеет несколько значений, разделенных запятой.

Ответы [ 4 ]

3 голосов
/ 29 марта 2012

Я думаю, что fgets() и sscanf() ваш друг:

int parseTokens(FILE *filePtr, char **tokens, char **values)
{
    int i = 0;

    char line[128];

    while (fgets(line, 127, filePtr)) {
        tokens[i] = malloc(64);
        values[i] = malloc(64);

        sscanf(line, "%s %s", tokens[i], values[i]);

        i++;
    }

    return i;
}

int main(void)
{
    char *tokens[20];
    char *values[20];

    FILE *filePtr = fopen("~/test.txt", "r");

    if (!filePtr)
    {
        fprintf(stderr, "Error opening file: %s", strerror(errno));
    }

    int count = parseTokens(filePtr, tokens, values);

    for (int i = 0; i < count; i++) {
        printf("%s %s\n", tokens[i], values[i]);

        free(tokens[i]);
        free(values[i]);
    }

    fclose(filePtr);
}
2 голосов
/ 29 марта 2012

Используя getc(), считывайте символы из входного потока в буфер для каждой строки. Как только вы нажмете токен-разделитель, вы strncpy() или strdup() буфера для каждой строки попадете в токен char*. При необходимости снова проанализируйте токен по внутреннему разделителю токена (такому как запятая), захватывая символ за раз и сохраняя его в буфере для каждого токена, пока не попадете в разделитель внутри токена. Как только вы попали в разделитель строк, скопируйте буфер для каждой строки в значение char*. Если вы знаете, что значением является int, float и т. Д., Используйте функции C для преобразования char* в эти примитивы (например, strtol() и т. Д.). Если у вас есть несколько пар токен-значение, сохраните массив токенов или указатели на токен и укажите значение char* переменных. Повторяйте до EOF (конец файла).

1 голос
/ 29 марта 2012

Попробуйте это:

    FILE* fp;
    fp = fopen("in.txt","r");

    if(fp == NULL)
    {
        printf("Can't open/read file.\n");
        exit(1);
    }

    char* buf = NULL;
    char* key = malloc(64);
    char* val = malloc(64);
    size_t read;
    size_t len = 0;

    if(key == NULL || val == NULL)
    {
        printf("malloc failed.\n");
        exit(1);
    }


    while((read = getline(&buf, &len, fp)) != -1)
    {
        sscanf(buf,"%s %s", key, val);
        printf("<%s> <%s>\n", key, val);
    }

    if(buf != NULL)
    {
      free(buf);
    }

    free(key);
    free(val);

    fclose(fp);

in.txt Файл:

key value
key1 value1

Приложение C Выход:

<key> <value>
<key1> <value1>

Надеюсь, это поможет вам.

0 голосов
/ 29 марта 2012

как насчет использования regexp?если вы в Linux, вы можете просто #include <regexp.h> использовать его.и man regexp.h получит, как его использовать.хранить их по строке.и, если они числа, используйте sprintf, чтобы перевести их в цвет.

...