【问题标题】:C++ how to read __int16_t integer using scanf functionC++如何使用scanf函数读取__int16_t整数
【发布时间】:2017-03-23 08:22:58
【问题描述】:

使用scanf读取指定宽度的整数。

#include <cstdio>

using namespace std;

int main(){
   __int16_t a;
   __int32_t b;
   scanf("%d %d", &a, &b)
   return 0;
}

有一个编译器警告说格式说明符“%d”需要 'int *' arg 而不是 '__int16_t *' 那么如何解决呢?
BTW C++11 是不允许的!

【问题讨论】:

  • __int24_t 没有格式说明符,因为这不是标准数据类型 - 也许您的编译器对此有一些特殊的扩展(尽管对于整数类型来说它的宽度很奇怪)
  • 另外你应该更喜欢使用 C++11 fixed-width integer types
  • scanf 支持一组有限的数据类型。查看this link 中的format 参数说明,熟悉支持的内容。
  • 在 C++ 中使用 std::cin 代替。它的类型更安全

标签: c++ scanf


【解决方案1】:

标准std::scanf 只支持标准类型。除非您的标准库记录了允许使用非标准类型的格式说明符,否则您不能使用它来读入非标准类型。如果是这样,那么只需按照他们的文档进行操作即可。

您可以尝试先扫描成标准类型,然后屏蔽多余的位(如果有),然后进行转换。如果输入不会溢出预期的目标类型,那么屏蔽是多余的。

long temp_a, temp_b; // could use short or int for temp_a
std::scanf("%ld %ld", &temp_a, &temp_b);
__int16_t a = temp_a & 0xffff;
__int32_t b = temp_b & 0xffffffff;

为了完整起见,如果可以使用 C++11,它们有标准的固定宽度类型:

std::int16_t a;
std::int32_t b;
std::scanf("%" PRId16 "%" PRId32, &a, &b)

或者,如果您的流媒体库有非标准类型的重载,请使用std::cin。这样你就可以处理无效的输入。

【讨论】:

    【解决方案2】:

    __int16_t 可能是一个(编译器特定的)类型,它是一个 16 位有符号整数。 scanf() 通常不支持此类特定于编译器的类型(如果支持,则需要特定于您的编译器和库的格式说明符)。

    在下文中,我假设编译器支持 __int16_t 作为 16 位有符号整数类型,而 scanf() 不提供任何读取方式。

     long int some_int;    //  range at least [-2147483647,2147483647]
     __int16_t a;
     if (scanf("%ld ", &some_int) == 1)
     {
          //   report error if some_int outside range a __int16_t can represent
    
          a = some_int;
     }
     else
     {
           // an error occurred
     }
    

    我没有在上面使用int%d 格式说明符,因为C++ 标准只需要int 就能够表示-3276732767 的范围(尽管允许范围更大)。可以想象,编译器的int 可以表示-3267832767 的范围,但__int16_t 表示-3276732768 的范围。在这样的设置中,如果上面的代码使用int而不是long int,则可能无法正确处理32768的输入。

    就个人而言,我可能会尝试使用 C++ istream(例如 std::cin &gt;&gt; a)而不是 C 的 scanf(),因为实际上它很可能会起作用。原因是,如果一个实现支持像__int16_t 这样的类型,那么在istream 中包含对它的支持的努力比在scanf() 中支持它的努力要少。

    【讨论】:

    • 我建议删除%ld 之后的空格,因为它会丢弃空白字符直到第一个非空白字符,这将阻止输入,直到出现其他非空白字符输入。
    【解决方案3】:

    对 __int16_t 使用“%d”。我不知道 '__int24_t' 存在。更多信息:How to use int16_t or int32_t with functions like scanf

    【讨论】:

    • Use '%d' for __int16_t 当且仅当sizeof (int) == 2 有效,这在现代系统中很少见。此外,这应该是一个评论,而不是回答(是的,我知道你没有足够的代表为 cmets,但这并不意味着你可以发布半生不熟的答案)。
    • 当使用%d 代表__int16_t 时,OP 也会收到警告
    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    相关资源
    最近更新 更多