sscanf с массивом членов структуры struct - PullRequest
0 голосов
/ 30 октября 2018

Я обнаружил это неожиданное поведение при написании кода для Arduino и смог повторить то же самое в MSVC15:

struct IDCount
{
    uint16_t count;
    char ID[20];
};
void test06b()
{
    IDCount item;
    char str[] = "0411010103, 8";
    char str1[20];

    // writing to struct member char array
    int res1 = sscanf(str, "%[^,], %d", item.ID, &item.count);
    printf("[%d] id: [%s]\tcount: [%d]\n", res1, item.ID, &item.count);

    // writing to a char array
    int res2 = sscanf(str, "%[^,], %d", str1, &item.count);
    printf("[%d] id: [%s]\tcount: [%d]\n", res2, str1, &item.count);
}

Результаты:

[2] id: []    count: [8]
[2] id: [0411010103]  count: [8]    

Я потратил немало времени на проверку спецификатора формата, прежде чем сузился до проблемы с массивом struct char. Почему не работает массив char в структуре? Есть идеи?

Заранее спасибо.

Обновление Переход с uint16_t на int работает.

1 Ответ

0 голосов
/ 30 октября 2018

Вы используете неверный спецификатор формата для чтения item.count. Для uint16_t вы должны использовать "%"SCNd16 или "%"SCNu16 вместо "%d".

Поскольку int на большинстве современных платформ имеет длину 32 бита, данные, записанные в item.count, перетекают в item.ID. В архитектуре с прямым порядком байтов, со значением, вписывающимся в uint16_t, переполняющие байты будут равны нулю, фактически завершая строку в вашем буфере в позиции 0.

Вы можете попытаться ввести отрицательное значение для item.count в исходной строке и увидеть первые два байта item.ID, перезаписанные 0xFFs.

...