1
#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中读取 auint64_t和 a ,但每次尝试此操作时char它只读取它ui(断言失败)。ret == 2

4

3 回答 3

4

你这里有两个问题。第一的

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

并得到相同的结果。

于 2018-11-02T14:02:26.560 回答
3

您的格式字符串需要字符64跟随整数。%lu是格式说明符;64是文字字符。

于 2018-11-02T13:47:56.177 回答
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

于 2018-11-02T14:04:14.853 回答