Вы можете адаптировать свое существующее решение следующим образом:
- Как указано в вашем вопросе и ответе @wilx, используйте спецификатор формата
%n
и передайте дополнительный параметр int
в sscanf
для захвата количества потребляемых символов (которое также будет индексом любых завершающих данных). - Вместо
const
char *
, проход адрес одного char
для обнаружения присутствия конечных данных. - Используйте возвращаемое значение из
sscanf
для проверки количества проанализированных элементов ( 7 будет подходящим для вашего случая использования); меньшее число будет означать сбой в середине анализа, а большее число будет означать конечные данные.
Вот рабочий пример (не охватывающий все крайние случаи, но должен быть отправной точкой):
#include <stdio.h>
#include <time.h>
static void parse_time(const char* pszValue, struct tm* pstm, int* piItemsParsed, int* piCharsConsumed, char* pcFollow)
{
float dSec;
char cSeparator;
*piItemsParsed = sscanf( pszValue, "%4d-%2d-%2d%c%2d:%2d:%f%n%c",
&pstm->tm_year, &pstm->tm_mon, &pstm->tm_mday, &cSeparator,
&pstm->tm_hour, &pstm->tm_min, &dSec, piCharsConsumed, pcFollow );
printf("Time String = '%s'\n", pszValue);
printf("Items Parsed = %d\n", *piItemsParsed);
printf("Chars Consumed = %d\n", *piCharsConsumed);
printf("Char Following = 0x%02x\n", (unsigned int) *pcFollow);
}
static void report(const char* pszValue, int iItemsParsed, int iCharsConsumed)
{
if (iItemsParsed == 7)
{
printf("Timestamp is valid\n");
}
else
{
printf("Timestamp has trailing data: '%s'\n", pszValue + iCharsConsumed);
}
}
static void parse_and_report(const char* pszValue, struct tm* pstm)
{
int iItemsParsed;
int iCharsConsumed;
char cFollow;
parse_time(pszValue, pstm, &iItemsParsed, &iCharsConsumed, &cFollow);
report(pszValue, iItemsParsed, iCharsConsumed);
}
int main(void)
{
struct tm stm;
static const char pszValue[] = "2020-03-01 07:31:30.345";
static const char pszValue2[] = "2020-03-01 07:31:30.345trailing data";
static const char pszValue3[] = "2020-03-01 07:31:30.345 more trailing data";
static const char pszValue4[] = "2020-03-01 07:31:30.345\nyet more trailing data";
parse_and_report(pszValue, &stm);
parse_and_report(pszValue2, &stm);
parse_and_report(pszValue3, &stm);
parse_and_report(pszValue4, &stm);
return 0;
}
Пример вывода:
Time String = '2020-03-01 07:31:30.345'
Items Parsed = 7
Chars Consumed = 23
Char Following = 0x00
Timestamp is valid
Time String = '2020-03-01 07:31:30.345trailing data'
Items Parsed = 8
Chars Consumed = 23
Char Following = 0x74
Timestamp has trailing data: 'trailing data'
Time String = '2020-03-01 07:31:30.345 more trailing data'
Items Parsed = 8
Chars Consumed = 23
Char Following = 0x20
Timestamp has trailing data: ' more trailing data'
Time String = '2020-03-01 07:31:30.345
yet more trailing data'
Items Parsed = 8
Chars Consumed = 23
Char Following = 0x0a
Timestamp has trailing data: '
yet more trailing data'