Пространство обработки strptime в фиксированной строке формата

Есть ли способ получить strptime() обрабатывать строки фиксированного формата времени?

Мне нужно проанализировать строку времени, которая всегда в формате фиксированной ширины: "yymmdd HHMMSS", но с осложнением, что ведущие нули иногда присутствуют, а иногда нет.

Чтение на странице man(3p) strptime Отмечу, что для всех спецификаторов преобразования %y, %m, %d, %H, %M, %S отмечается, что "начальные нули допускаются, но не обязательны". Поэтому я пытаюсь спецификатор формата %y%m%d %H%M%S, наивно надеясь, что strptime признает, что пробелы в двух подстрока %y%m%d а также %H%M%S эквивалентны (отсутствуют) ведущие нули.

Кажется, это работает для спецификатора %m, но не для %M (хорошо, если вторая часть меньше 10), как показано в следующем фрагменте кода

#include <stdio.h>
#include <time.h>


int main() {
   struct tm buff;
   const char ts[]="17 310 22 312";
   char st[14];

   strptime(ts,"%y%m%d %H%M%S", &buff);
   strftime(st,14,"%y%m%d %H%M%S",&buff);

   printf("%s\n",ts);
   printf("%s\n",st);
   return 0;
}

При компиляции и запуске на моей машине выводов

17 310 22 312
170310 223102

Любое понимание того, как преодолеть это, будет оценено, или мне нужно прибегнуть к ручному измельчению строки из 2 символов в то время, используя atoi преобразовать в целые числа, чтобы заполнить мой struct tm экземпляр с?

1 ответ

Решение

Было бы лучше получить код, который генерирует данные с фиксированным форматом Wonky.

Предполагая, что это не может быть сделано сегодня утром, тогда, возможно, вам следует канонизировать (копию) шатких данных, например так:

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

static inline void canonicalize(char *str, int begin, int end)
{
    for (int i = begin; i <= end; i++)
    {
        if (str[i] == ' ')
            str[i] = '0';
    }
}

int main(void)
{
    struct tm buff;
    const char ts[] = "17 310 22 312";
    char st[32];

    char *raw = strdup(ts);

    printf("[%s] => ", raw);
    canonicalize(raw, 0, 5);
    canonicalize(raw, 7, 12);
    printf("[%s] => ", raw);
    strptime(raw, "%y%m%d %H%M%S", &buff);
    strftime(st, sizeof(st), "%y%m%d %H%M%S", &buff);
    printf("[%s] => ", st);
    strftime(st, sizeof(st), "%Y-%m-%d %H:%M:%S", &buff);
    printf("[%s]\n", st);
    free(raw);
    return 0;
}

canonicalize() Функция Converts заменяет пробелы нулями в заданном диапазоне строки. Понятно, что если вы укажете начальную и конечную точки, которые находятся за пределами границ, они будут растоптаны за пределами границ. Я сохранил const на ts и сделал копию с strdup(); если вы можете рассматривать строку как переменные данные, вам не нужно делать (или освобождать) копию.

Выход из этого кода:

[17 310 22 312] => [170310 220312] => [170310 220312] => [2017-03-10 22:03:12]
Другие вопросы по тегам