Разбор строки на основе исходного формата - PullRequest
2 голосов
/ 20 ноября 2011

Я пытаюсь разобрать набор строк и извлечь определенные части строки на основе исходного формата (чтение файла конфигурации).

Еще немного объяснений: формат может содержать до 4 части для форматирования.В этом случае %S пропустит часть, %a-%c извлечет часть и будет рассматриваться как строка, %d как int.

То, что я пытаюсь сделать сейчас, - это придуматькакой-то умный способ разобрать это.До сих пор я придумал следующий прототип.Тем не менее, моя арифметика указателей все еще нуждается в некоторой работе для пропуска / извлечения частей.

В конечном итоге каждая часть будет сохранена в массиве структур.

Редактировать: с использованием sscanf может не работать в этом случае, так как формат указан в файле конфигурации.Кроме того, формат может масштабироваться, строка (и тип) может меняться.

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

#define DIM(x) (sizeof(x)/sizeof(*(x)))

void process (const char *fmt, const char *line) {
   char c;
   const char *src = fmt;
   while ((c = *src++) != '\0')
   {   
      if (c == 'S');      // skip part
      else if (c == 'a'); // extract %a
      else if (c == 'b'); // extract %b
      else if (c == 'c'); // extract %c
      else if (c == 'd'); // extract %d (int)
      else { 
         printf("Unknown format\n");
         exit(1);
      }   
   }
}

static const char *input[] = {
   "bar 200.1 / / (zaz) - \"bon 10\"",
   "foo 100.1 / / (baz) - \"apt 20\"",
};

int main (void) {
   const char *fmt = "%S %a / / (%b) - \"%c %d\"";
   size_t i;
   for(i = 0; i < DIM (input); i++) 
   {
      process (fmt, input[i]);
   }   
   return (0);
}

Ответы [ 2 ]

1 голос
/ 20 ноября 2011

выражений scanf иногда достаточно мощны для анализа фактического ввода, и их можно построить во время выполнения или во время компиляции.Итак, я бы попробовал пойти по этому пути, прежде чем изобретать велосипед:

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

#define DIM(x) (sizeof(x)/sizeof(*(x)))

static const char *input[] = {
   "bar 200.1 / / (zaz) - \"bon 10\"",
   "foo 100.1 / / (baz) - \"apt 20\"",
};
const char *format = "%*[^ ] %[^ ] / / (%[^)]) - \" %[^ ] %d \"";

int main()
{
 typedef char buffer[100];
 buffer A,B,C;
 int D, i, p;

 for (i = 0; i < DIM(input); i++) {
  if ((p = sscanf(input[i], format, A, B, C, &D)) == 4)
   printf("%s %s %s %d\n", A, B, C, D);
  else
   printf("parsed only %d\n", p);
 }
}

производит:

200.1 zaz bon 10
100.1 baz apt 20
0 голосов
/ 20 ноября 2011

анализ в соответствии с форматом может быть затруднен без строгих определений каждого заполнителя. Как вы планируете обращаться с делами, как:

fmt = "(%c)";

input = "(a)bc)";

ясно, что пользователь хотел получить "a) bc", но, поскольку ')' был вашим токеном конечного анализа, вы получили только "a"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...