C ++ 11 int8_t buggy输入/输出

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++ 11 int8_t buggy输入/输出相关的知识,希望对你有一定的参考价值。

这是我的程序中的代码片段。我正在使用int8_t数据类型,我在输入/输出方面遇到了一些问题。显然,在程序中使用int8_t需要为-std=c++11编译器设置g++标志。我这样做了,但是有运行时错误。这是我的代码:

#include <iostream>
#include <cstdint>
using std::cout;
using std::cin;
using std::endl;
int main() {
  int8_t number;

  cout << "Enter a number [1-100]: ";
  cin >> number;
  cout << "You entered: " << number << endl;
  cout << number << " / 10 = " << (number / 10) << endl;

  return 0;
}

这是程序的输出:

 $ ./a.out
Enter a number [1-100]: 95
You entered: 9
9 / 10 = 5

$是shell提示符。无论如何,似乎只从输入流中读取第一个数字。即便如此,整数除法9 / 10应该返回0,而不是5。这个程序旨在做95 / 10并返回9的结果。从理论上讲,这个程序应该可行,但显然,即使是除法运算符也是错误的。我应该注意,使用int而不是int8_t会导致程序按预期工作。我怀疑在这种情况下,有人会告诉我使用int数据类型并处理它。但我们是软件工程师!我想知道int8_t数据类型是否存在固有的缺陷。为什么它不能接受正确的用户输入,还会破坏除法运算符?!任何值得使用的编程语言都必须没有这些不完美之处。我认为C ++很受欢迎,最终有人意识到int8_t在某种意义上是有缺陷的。这是我需要知道的复杂性。

答案

首先,C ++中最小的类型是char,而在大多数系统中,最后几十年等于8位字节。所以类型int8_t通常是signed char的别名。

其次,当使用char运算符从流中读取signedunsigned>>)时,它会读取一个字符。如果使用别名类型(如int8_t)并不重要,它仍然是char类型并将被读作字符。

因此,结果是您读取了单个字符,并且该字符的编码值存储在变量number中。使用ASCII encoding(这些天最常见的字符编码)变量number将存储整数值57(字符'9'的ASCII)除以10等于整数5

如果要读取小整数,请使用int作为类型。如果你想将它存储在一个字节中(使用int8_t),你必须使用临时的int变量,或者将变量转换为int。这个拼接也必须用于打印(因为否则将使用char操作符的<<重载)所以我建议默认使用普通的int类型用于任何整数。

使用比int更小的类型只有在读取/写入原始二进制数据时才有意义,或者您使用的是非常小的嵌入式系统,其中每个字节(或者甚至是位)都很重要。

另一答案

所以反思一些程序员家伙的帖子,我想添加自己的印象。似乎由于int8_tchar的别名,coutcin自动将变量视为char,并进行字符输入/输出。我找到了解决这个问题的方法,并且实际上对变量进行了整数用户输入/输出。这很简单。我使用C编程语言函数printf()scanf()来完成这项工作。这些函数具有格式说明符,允许您将变量视为任何数据类型。 coutcin自动解释数据类型,你可以手动为printf()scanf()做,这给你一定程度的力量。现在我的代码看起来像这样:

#include <iostream>
#include <cstdint>
#include <cstdio>  // you need this for printf() and scanf()
using std::cout;
using std::cin;
using std::endl;
int main() {
  int8_t number;

  cout << "Enter a number [1-100]: ";
  // %hhd allows you to treat int8_t as an integer data type, instead of
  // a character
  scanf("%hhd", &number);
  printf("You entered: %hhd
", number);
  printf("%hhd / 10 = %hhd
", number, (number / 10));

  return 0;
}

实际输出如下:

$ ./a.out
Enter a number [1-100]: 95
You entered: 95
95 / 10 = 9

这是一个黑客但它的工作原理!好吧,你每天都学到新东西。


编辑这个答案,我想为那些想要做更多研究的人添加一些相关问题的相关链接。

Are int8_t and uint8_t intended to be char types?

Difference between int32, int, int32_t, int8 and int8_t

以上是关于C ++ 11 int8_t buggy输入/输出的主要内容,如果未能解决你的问题,请参考以下文章

int32,int,int32_t,int8和int8_t之间的区别

为什么通过cin的int8_t和用户输入显示奇怪的结果[重复]

int32、int、int32_t、int8和int8_t的区别

这个int8_t范围到底是啥?

HTML HTML表的Buggy CSS(示例)

New Year and Buggy Bot