diff --git a/include/fmt/printf.h b/include/fmt/printf.h index e25e6fba..03c8746d 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -545,6 +545,9 @@ void vprintf(buffer& buf, basic_string_view format, if (it == end) report_error("invalid format string"); char type = static_cast(*it++); if (is_integral_type(arg.type())) { + // The '+' and space flags only apply to signed conversions. + if (type == 'u' || type == 'o' || type == 'x' || type == 'X') + specs.set_sign(sign::none); // Normalize type. switch (type) { case 'i': diff --git a/test/printf-test.cc b/test/printf-test.cc index f8322522..e2a06f8d 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -169,6 +169,14 @@ TEST(printf_test, plus_flag) { // '+' flag and space flag are both ignored for non-numeric types. EXPECT_PRINTF("x", "%+ c", 'x'); EXPECT_PRINTF("x", "% +c", 'x'); + + // '+' flag is ignored for unsigned conversions. + EXPECT_PRINTF("42", "%+u", 42); + EXPECT_PRINTF("42", "%+o", 042); + EXPECT_PRINTF("2a", "%+x", 0x2a); + EXPECT_PRINTF("2A", "%+X", 0x2a); + EXPECT_PRINTF("0x002a", "%+#06x", 0x2a); + EXPECT_PRINTF("", "%+.0u", 0); } TEST(printf_test, minus_flag) { @@ -199,6 +207,12 @@ TEST(printf_test, space_flag) { // ' ' flag is ignored for non-numeric types. EXPECT_PRINTF("x", "% c", 'x'); + + // ' ' flag is ignored for unsigned conversions. + EXPECT_PRINTF("42", "% u", 42); + EXPECT_PRINTF("42", "% o", 042); + EXPECT_PRINTF("0002a", "% 05x", 0x2a); + EXPECT_PRINTF("2A", "% X", 0x2a); } TEST(printf_test, hash_flag) {