Почему sscanf не может прочитать uint64_t и символ из одной строки?

#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 не получается) каждый раз, когда я пробовал это.

1

Решение

У вас есть две проблемы здесь. Первый

%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]

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

3

Другие решения

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

3

Ваша строка формата неверна.
Это должно происходить так на 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

3
По вопросам рекламы [email protected]