#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
не получается) каждый раз, когда я пробовал это.
У вас есть две проблемы здесь. Первый
%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]
и получить те же результаты.
Ваша строка формата ожидает символы 64
следовать за целым числом. %lu
спецификатор формата; 64
буквальные символы.
Ваша строка формата неверна.
Это должно происходить так на 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