扫描二进制数的方法?
Way to scanf binary number?
我正在尝试编写一小段代码,我可以在其中扫描二进制数字,例如 00110011
,并将其作为数字转换为整数。所以 00110011
将是 51。
我为此编写的代码是这样的
int main()
{
unsigned char byte;
int d;
scanf("%8s", &byte);
d = byte;
printf("%d,%c",d, byte);
return 0;
}
但是,给我一个 48
的输出。 00000001
也给了我 48
,其他任何东西也是如此。
我知道出了什么问题,它将 0 和 1 的字符串视为单个 0
,并且由于其字符是 0x30
或 0d48
,因此它输出 48
。我不知道是否有办法绕过这个问题并将其扫描为二进制等价物。
您的代码根本不起作用:
- 您最多扫描 8 个字符加上一个空终止符,传递单字节变量的地址:这具有未定义的行为。
d = byte
不执行任何转换。字符 '0'
被读入 byte
并且其 ASCII 值存储在 d
中,即程序输出的 48
。
此外,scanf()
中没有二进制编码的标准转换说明符。读取字符串是一个很好的方法,但是你应该传递一个更大的缓冲区并使用循环转换为二进制:
#include <ctype.h>
#include <stdio.h>
int main() {
char buf[100];
/* read a sequence of at most 99 binary digits into buf */
if (scanf(" %99[01]", buf) == 1) {
unsigned int d = 0;
/* convert the binary digits one at a time into integer d */
for (int i = 0; buf[i]; i++) {
d = (d << 1) | (buf[i] - '0');
}
/* print value as a number */
printf("%s -> %d\n", buf, d);
if (d == (unsigned char)d && isprint(d)) {
/* print value as a character if printable */
printf("%s -> %c\n", buf, d);
}
}
return 0;
}
您还可以使用 strtoul()
将表示为二进制数字字符串(或任何其他基数最多为 36)的数字转换为:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char buf[100];
/* read a sequence of at most 99 binary digits into buf */
if (scanf(" %99[01]", buf) == 1) {
unsigned long d = strtoul(buf, NULL, 2);
/* print value as a number */
printf("%s -> %lu\n", buf, d);
if (d == (unsigned char)d && isprint((unsigned char)d)) {
/* print value as a character if printable */
printf("%s -> %c\n", buf, (unsigned char)d);
}
}
return 0;
}
但是请注意,strtoul()
的行为将不同于第一个代码:strtoul()
将 return ULONG_MAX
溢出,而第一个示例将只计算二进制字符串的低位。
我发现这个简单的函数应该很容易理解,而且它确实有效。它是一种算法,遵循您在现实生活中用笔和纸自然地完成它的方式,但是当您编译它(gcc 命令)以包含数学库时,您将需要 -lm,但是您可以绕过 pow( ) 并包括问题,如果你只是做一个 for 循环。
#include <stdio.h>
#include <math.h>
int todecimal(long bno){
int dno = 0, i = 0, rem;
while (bno != 0) {
rem = bno % 10;
bno /= 10;
dno += rem * pow(2, i);
++i;
}
return dno;
}
我正在尝试编写一小段代码,我可以在其中扫描二进制数字,例如 00110011
,并将其作为数字转换为整数。所以 00110011
将是 51。
我为此编写的代码是这样的
int main()
{
unsigned char byte;
int d;
scanf("%8s", &byte);
d = byte;
printf("%d,%c",d, byte);
return 0;
}
但是,给我一个 48
的输出。 00000001
也给了我 48
,其他任何东西也是如此。
我知道出了什么问题,它将 0 和 1 的字符串视为单个 0
,并且由于其字符是 0x30
或 0d48
,因此它输出 48
。我不知道是否有办法绕过这个问题并将其扫描为二进制等价物。
您的代码根本不起作用:
- 您最多扫描 8 个字符加上一个空终止符,传递单字节变量的地址:这具有未定义的行为。
d = byte
不执行任何转换。字符'0'
被读入byte
并且其 ASCII 值存储在d
中,即程序输出的48
。
此外,scanf()
中没有二进制编码的标准转换说明符。读取字符串是一个很好的方法,但是你应该传递一个更大的缓冲区并使用循环转换为二进制:
#include <ctype.h>
#include <stdio.h>
int main() {
char buf[100];
/* read a sequence of at most 99 binary digits into buf */
if (scanf(" %99[01]", buf) == 1) {
unsigned int d = 0;
/* convert the binary digits one at a time into integer d */
for (int i = 0; buf[i]; i++) {
d = (d << 1) | (buf[i] - '0');
}
/* print value as a number */
printf("%s -> %d\n", buf, d);
if (d == (unsigned char)d && isprint(d)) {
/* print value as a character if printable */
printf("%s -> %c\n", buf, d);
}
}
return 0;
}
您还可以使用 strtoul()
将表示为二进制数字字符串(或任何其他基数最多为 36)的数字转换为:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char buf[100];
/* read a sequence of at most 99 binary digits into buf */
if (scanf(" %99[01]", buf) == 1) {
unsigned long d = strtoul(buf, NULL, 2);
/* print value as a number */
printf("%s -> %lu\n", buf, d);
if (d == (unsigned char)d && isprint((unsigned char)d)) {
/* print value as a character if printable */
printf("%s -> %c\n", buf, (unsigned char)d);
}
}
return 0;
}
但是请注意,strtoul()
的行为将不同于第一个代码:strtoul()
将 return ULONG_MAX
溢出,而第一个示例将只计算二进制字符串的低位。
我发现这个简单的函数应该很容易理解,而且它确实有效。它是一种算法,遵循您在现实生活中用笔和纸自然地完成它的方式,但是当您编译它(gcc 命令)以包含数学库时,您将需要 -lm,但是您可以绕过 pow( ) 并包括问题,如果你只是做一个 for 循环。
#include <stdio.h>
#include <math.h>
int todecimal(long bno){
int dno = 0, i = 0, rem;
while (bno != 0) {
rem = bno % 10;
bno /= 10;
dno += rem * pow(2, i);
++i;
}
return dno;
}