Почему sscanf не может прочитать uint64_t и символ из одной строки? - PullRequest
0 голосов
/ 02 ноября 2018
#include <cstdio>
#include <cstdint>
#include <cassert>

int main() {
    std::uint64_t ui;
    char c;
    auto ret = std::sscanf("111K", "%lu64%[B, K, M, G]", &ui, &c);

    assert(ret == 2);
    assert(ui == 111);
}

Я пытался использовать sscanf для чтения uint64_t и char из одной строки, но он читал только ui (утверждение ret == 2 не удается) каждый раз, когда пытался это сделать.

Ответы [ 3 ]

0 голосов
/ 02 ноября 2018

У вас есть две проблемы здесь. Во-первых

%lu64

должно быть

"%" SCNu64 

для чтения в 64-битном целом числе.

Второй выпуск -

%[B, K, M, G]

требует char* или wchar_t* в качестве выходного параметра, поскольку он заполняет c-строку. Вам нужно изменить

char c;

по крайней мере

char c[2] // 2 because it adds a null terminator

в порядке захвата K. Мы собрали все это вместе и получили

auto ret = std::sscanf("111K", "%" SCNu64 "%[B, K, M, G]", &ui, c);

Обратите внимание, что

%[B, K, M, G]

фактически пытается сопоставить все пробелы и запятые внутри скобок. Вы также можете написать это как

%[BKMG]

и получите те же результаты.

0 голосов
/ 02 ноября 2018

Ваша строка формата неверна. Это должно происходить так на 64-битных сборках: "%lu%1[BKMG]" и "%llu%1[BKMG]" при сборке для 32-битных.

В универсальном решении используется макрос SCNu64: "%" SCNu64 "%1[BKMG]". Этот макрос определен в заголовочном файле cinttypes.

Также ваш последний параметр передан неправильно. Это должен быть массив символов, так как в конце будет добавлен ноль. Ваш код ведет к неопределенному поведению, так как, когда будет записано значение c, также будет записано что-то за пределами этой переменной.

#include <cstdio>
#include <cstdint>
#include <cassert>
#include <iostream>

int main() {
    std::uint64_t ui;
    char s[32];
    auto ret = std::sscanf("111K", "%lu%1[BKMG]", &ui, s);

    std::cout << "ret=" << ret << "  ui=" << ui << " s=" << s << "\n";

    return 0;
}

https://wandbox.org/permlink/17vZ8OkydJ7zQmP4
https://wandbox.org/permlink/z21Rbsu4mAseZyS4

0 голосов
/ 02 ноября 2018

В строке формата ожидается, что символы 64 будут следовать за целым числом. %lu - спецификатор формата; 64 являются буквальными символами.

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