C++ 11 int8_t 错误 input/output
C++ 11 int8_t buggy input/output
这是我程序中的一段代码。我使用的是 int8_t
数据类型,但我在使用 input/output 时遇到了一些问题。显然,在程序中使用 int8_t
需要为 g++
编译器设置 -std=c++11
标志。我这样做了,但是有运行时错误。这是我的代码:
#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
应该return0
,而不是5
。该程序旨在执行 95 / 10
和 return 9
的结果。从理论上讲,这个程序应该可以工作,但显然,即使是除法运算符也有问题。我应该注意,使用 int
而不是 int8_t
会使程序按预期工作。我怀疑在这种情况下,有人只会告诉我使用 int
数据类型并进行处理。但我们是软件工程师!我想知道 int8_t
数据类型是否存在固有缺陷。为什么它不能接受正确的用户输入,还破坏了除法运算符?!任何值得使用的编程语言都必须没有这样的缺陷。而且我认为 C++ 非常流行,最终有人意识到 int8_t
在某种意义上是有缺陷的。那是我需要知道的错综复杂的事情。
首先,C++ 中最小的类型是 char
,在过去几十年的大多数系统中,它等于一个 8 位字节。所以类型 int8_t
通常是 signed char
.
的别名
其次,当使用 >>
运算符从流中读取 char
(signed
或 unsigned
)时,它会读取 字符。如果使用别名类型(如 int8_t
)并不重要,它仍然是 char
类型并将被读取为字符。
因此结果是您读取了单个字符,并且该字符的编码值存储在您的变量number
中。使用 ASCII encoding(当今最常见的字符编码),变量 number
将存储整数值 57
(字符 '9'
的 ASCII)除以 10
等于整数 5
.
如果要读取小整数,类型使用int
。如果你想将它存储在一个字节中(使用 int8_t
),你必须使用临时 int
变量,或者将变量转换为 int
。这种转换也必须为打印完成(否则将使用 <<
运算符的 char
重载)所以我建议默认情况下对任何整数使用普通 int
类型。
使用比 int
更小的类型只有当你 read/write 原始二进制数据时才有意义,或者你在一个非常小的嵌入式系统上,每个字节(甚至可能 位)计数。
所以反思一些程序员的post,我想补充一下我自己的印象。似乎由于 int8_t
是 char
的别名,cout
和 cin
自动将变量视为 char
,并执行 字符 input/output。我找到了解决这个问题的方法,实际上对变量执行 integer user input/output 。这很简单。我使用 C 编程语言函数 printf()
和 scanf()
来完成这项工作。这些函数具有格式说明符,允许您将变量视为任何数据类型。 cout
和 cin
会自动解释数据类型,而您可以为 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\n", number);
printf("%hhd / 10 = %hhd\n", number, (number / 10));
return 0;
}
实际输出如下所示:
$ ./a.out
Enter a number [1-100]: 95
You entered: 95
95 / 10 = 9
这是一个 hack,但它确实有效!好吧,你每天都能学到新东西。
编辑这个答案,我想为那些想做更多研究的人添加一些相关问题的相关链接。
Are int8_t and uint8_t intended to be char types?
Difference between int32, int, int32_t, int8 and int8_t
这是我程序中的一段代码。我使用的是 int8_t
数据类型,但我在使用 input/output 时遇到了一些问题。显然,在程序中使用 int8_t
需要为 g++
编译器设置 -std=c++11
标志。我这样做了,但是有运行时错误。这是我的代码:
#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
应该return0
,而不是5
。该程序旨在执行 95 / 10
和 return 9
的结果。从理论上讲,这个程序应该可以工作,但显然,即使是除法运算符也有问题。我应该注意,使用 int
而不是 int8_t
会使程序按预期工作。我怀疑在这种情况下,有人只会告诉我使用 int
数据类型并进行处理。但我们是软件工程师!我想知道 int8_t
数据类型是否存在固有缺陷。为什么它不能接受正确的用户输入,还破坏了除法运算符?!任何值得使用的编程语言都必须没有这样的缺陷。而且我认为 C++ 非常流行,最终有人意识到 int8_t
在某种意义上是有缺陷的。那是我需要知道的错综复杂的事情。
首先,C++ 中最小的类型是 char
,在过去几十年的大多数系统中,它等于一个 8 位字节。所以类型 int8_t
通常是 signed char
.
其次,当使用 >>
运算符从流中读取 char
(signed
或 unsigned
)时,它会读取 字符。如果使用别名类型(如 int8_t
)并不重要,它仍然是 char
类型并将被读取为字符。
因此结果是您读取了单个字符,并且该字符的编码值存储在您的变量number
中。使用 ASCII encoding(当今最常见的字符编码),变量 number
将存储整数值 57
(字符 '9'
的 ASCII)除以 10
等于整数 5
.
如果要读取小整数,类型使用int
。如果你想将它存储在一个字节中(使用 int8_t
),你必须使用临时 int
变量,或者将变量转换为 int
。这种转换也必须为打印完成(否则将使用 <<
运算符的 char
重载)所以我建议默认情况下对任何整数使用普通 int
类型。
使用比 int
更小的类型只有当你 read/write 原始二进制数据时才有意义,或者你在一个非常小的嵌入式系统上,每个字节(甚至可能 位)计数。
所以反思一些程序员的post,我想补充一下我自己的印象。似乎由于 int8_t
是 char
的别名,cout
和 cin
自动将变量视为 char
,并执行 字符 input/output。我找到了解决这个问题的方法,实际上对变量执行 integer user input/output 。这很简单。我使用 C 编程语言函数 printf()
和 scanf()
来完成这项工作。这些函数具有格式说明符,允许您将变量视为任何数据类型。 cout
和 cin
会自动解释数据类型,而您可以为 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\n", number);
printf("%hhd / 10 = %hhd\n", number, (number / 10));
return 0;
}
实际输出如下所示:
$ ./a.out
Enter a number [1-100]: 95
You entered: 95
95 / 10 = 9
这是一个 hack,但它确实有效!好吧,你每天都能学到新东西。
编辑这个答案,我想为那些想做更多研究的人添加一些相关问题的相关链接。
Are int8_t and uint8_t intended to be char types?
Difference between int32, int, int32_t, int8 and int8_t