Использование MPLAB для написания кода PIC16 на C с помощью компилятора XC8.
Я пытаюсь записать некоторые настройки скорости передачи данных из строки, например «115200,8,N,1». Для целей моего приложения я решил использовать перечисление для проверки четности (N,O,E становится 0,1,2).
У меня есть следующий код:
#include <stdint.h>
int main(void)
{
uint32_t baudrate;
uint8_t databits, parity, stopbits;
char *input = "115200,8,0,1";
sscanf(input, "%lu,%u,%u,%u", &baudrate, &databits, &parity, &stopbits);
printf("%lu - %u - %u - %u\n", baudrate, databits, parity, stopbits);
return 0;
}
И я ожидаю следующего вывода:
>> 115200 - 8 - 0 - 1
Однако я получаю:
>> 115200 - 0 - 0 - 1
Что я делаю не так, ведь всегда получается, что второй захват возвращает 0. Я предполагаю, что использую неправильные идентификаторы, но какие следует использовать?
Если бы ты приложил столько же усилий, чтобы ответить на вопрос @Yunnosch
Да, я пытался найти для вас ответ и предложил его. Просто сейчас внизу есть вариант получше. Вы не жалуетесь, что я трачу время, чтобы помочь вам получить помощь, о которой вы просите, не так ли? Если вы ссылаетесь на мое изменение, не стесняйтесь отменить его и посмотреть, какие отзывы вы получите от пользователей, которые пытаются помочь людям с проблемами регулярных выражений.
%u
сообщает sscanf
сопоставить десятичное целое число с необязательным знаком во входной строке, преобразовать его значение в unsigned int
и сохранить результат в unsigned int
, на который указывает соответствующий аргумент.
&databits
не указывает на unsigned int
. Как следствие, поведение программы не определяется стандартом C.
Точно так же %u
for &parity
и %u
for &stopbits
неверны, а %lu
for &baudrate
могут быть или не быть неправильными, в зависимости от особенностей реализации C.
Правильные символы спецификатора преобразования определяются макросами в заголовке <inttypes.h>
и могут использоваться следующим образом:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint32_t baudrate;
uint8_t databits, parity, stopbits;
char *input = "115200,8,0,1";
sscanf(input, "%" SCNu32 ",%" SCNu8 ",%" SCNu8 ",%" SCNu8,
&baudrate, &databits, &parity, &stopbits);
printf("%" PRIu32 " - %" PRIu8 " - %" PRIu8 " - %" PRIu8 "\n",
baudrate, databits, parity, stopbits);
return 0;
}
SCN
запускает макрос для символов преобразования scanf
, а затем u
для беззнакового целого типа, за которым следует количество битов. PRI
запускает аналогичный макрос для printf
конверсий. Эти макросы будут заменены строками в кавычках, а последовательные строки в кавычках в приведенном выше коде будут объединены в одну строку.
Например, "%" SCNu32 ",%" SCNu8 ",%" SCNu8 ",%" SCNu8
может оказаться эквивалентом %u,%hhu,%hhu,%hhu
.
Завершите напечатанные строки \n
. Это лучше работает с настройками C по умолчанию в отношении буфера и поведения оболочки.
Используйте return 0;
или верните EXIT_SUCCESS;
(определенный в <stdlib.h>
) в main
, чтобы выйти из успешного выполнения программы. Вы также можете передать управление до конца main
, чтобы завершить успешное выполнение программы. Используйте return EXIT_FAILURE;
, чтобы указать на неудачу. Вы можете использовать return 1;
в определенных средах, но помните, что он непереносим.
Это сработало @Eric Postpischil — спасибо!
Кроме того: проверка возвращаемого значения sscanf()
(равно ли оно 4?) перед вызовом printf("%" PRIu32 " - %" PRIu8 " - %" PRIu8 " - %" PRIu8 "\n", baudrate, databits, parity, stopbits);
является хорошей практикой.
Да, я согласен, что идентификаторы в sscan и/или printf неверны, но я надеялся получить некоторую поддержку относительно того, какими они должны быть. Моему компилятору нравится использовать
unsigned long
иunsigned char
, но тогда мне придется применить операциюatoi
к выводу.