char数组中的字节如何表示整数?
How can bytes in char array represent integers?
假设我有从二进制文件(如 ext2 格式的文件系统映像文件)中读取的 char 数组。
现在我需要读取从偏移字节 1024 开始的整数(<--这是从数据开始的偏移量)。有什么巧妙的方法吗?整数可以是任何数字。所以我相信在我的系统 (x86-64) 上可以用 4 字节的整数大小表示。
我相信我需要像这样使用 strtol:
/* Convert the provided value to a decimal long */
char *eptr=malloc(4);// 4 bytes becuase sizeof int is 4 bytes
....
int valread=read(fd,eptr,4);//fd is to ext2 formatted image file (from file system)
result = strtol(eptr, &v, 10);
上面是long
那么这个是表示32位整数的数字吗?
eptr
应该以 null 终止吗?
这是否正确?
在 strtol
的情况下,通过查看一些代码可能更容易理解。所以这里有一个非常简化的 strtol
类函数:
int string_to_int(const char *string)
{
// The integer value we construct and return
int value = 0;
// Loop over all the characters in the string, one by one,
// until the string null-terminator is reached
for (unsigned i = 0; string[i] != '[=10=]'; ++i)
{
// Get the current character
char c = string[i];
// Convert the digit character to its corresponding numeric value
int c_value = c - '0';
// Add the characters numeric value to the current value
value = (value * 10) + c_value;
// Note the multiplication with 10: That's because decimal numbers are base 10
}
// Now the string have been converted to its decimal integer value, return it
return value;
}
如果我们用字符串 "123"
调用它并展开循环发生的事情是这样的:
// First iteration
char c = string[0]; // c = '1'
int c_value = c - '0'; // c_value = 1
value = (value * 10) + c_value; // value = (0 * 10) + 1 = 0 + 1 = 1
// Second iteration
char c = string[0]; // c = '2'
int c_value = c - '0'; // c_value = 2
value = (value * 10) + c_value; // value = (1 * 10) + 2 = 10 + 2 = 12
// Third iteration
char c = string[0]; // c = '3'
int c_value = c - '0'; // c_value = 3
value = (value * 10) + c_value; // value = (12 * 10) + 3 = 120 + 3 = 123
在第四次迭代中,我们到达字符串 null-terminator 并且循环结束时 value
等于 int
值 123
.
我希望这能让大家更清楚地了解字符串到数字的转换是如何工作的。
虽然上面是字符串,如果你读取现有 int
值的原始二进制位,那么你不应该调用 strtol
因为数据不是字符串。
相反,您基本上将四个字节解释为一个 32 位值。
不幸的是,如果不了解关于 endianness 的一两件事,就很难解释这些位是如何解释的。
字节序是字节组成整数值的方式。采用(十六进制)数字 0x01020304
,它们可以存储为 0x01
、0x02
、0x03
和 0x04
(这称为 big-endian) ; 或如0x04
、0x03
、0x02
和0x01
(这叫little-endian)。
在 little-endian 系统(您的普通 PC-like 系统)上假设您有一个这样的数组:
char bytes[4] = { 0x04, 0x03, 0x02, 0x01 };
然后你可以把它复制到 int
:
int value;
memcpy(&value, bytes, 4);
这将使 int
变量 value
等于 0x01020304
。
I have char array that I read from binary file (like ext2 formatted filesystem image file).
以二进制模式打开文件
const char *file_name = ...;
FILE *infile = fopen(file_name, "rb"); // b is for binary
if (infile == NULL) {
fprintf(stderr, "Unable to open file <%s>.\n", file_name);
exit(1);
}
I need to read integer starting at offset byte 1024 ...
long offset = 1024;
if (fseek(infile, offset, SEEK_SET)) {
fprintf(stderr, "Unable to seek to %ld.\n", offset);
exit(1);
}
So I believe can be represented in integer size of 4 byte on my system
与其使用可能与 4 字节不同的 int
,不如考虑 int32_t
来自 <stdint.h>
。
int32_t data4;
if (fread(&data4, sizeof data4, 1, infile) != 1) {
fprintf(stderr, "Unable to read data.\n");
exit(1);
}
帐户 Endian。
因为文件数据是little-endian, convert to native endian. See #include <endian.h>
.
data4 = le32toh(data4);
完成后清理
// Use data4
fclose(infile);
believe I need to use strtol
like
没有。 strtol()
检查一个 字符串 和 returns 一个 long
。文件数据是二进制的,不是字符串。
假设我有从二进制文件(如 ext2 格式的文件系统映像文件)中读取的 char 数组。
现在我需要读取从偏移字节 1024 开始的整数(<--这是从数据开始的偏移量)。有什么巧妙的方法吗?整数可以是任何数字。所以我相信在我的系统 (x86-64) 上可以用 4 字节的整数大小表示。
我相信我需要像这样使用 strtol:
/* Convert the provided value to a decimal long */
char *eptr=malloc(4);// 4 bytes becuase sizeof int is 4 bytes
....
int valread=read(fd,eptr,4);//fd is to ext2 formatted image file (from file system)
result = strtol(eptr, &v, 10);
上面是long
那么这个是表示32位整数的数字吗?
eptr
应该以 null 终止吗?
这是否正确?
在 strtol
的情况下,通过查看一些代码可能更容易理解。所以这里有一个非常简化的 strtol
类函数:
int string_to_int(const char *string)
{
// The integer value we construct and return
int value = 0;
// Loop over all the characters in the string, one by one,
// until the string null-terminator is reached
for (unsigned i = 0; string[i] != '[=10=]'; ++i)
{
// Get the current character
char c = string[i];
// Convert the digit character to its corresponding numeric value
int c_value = c - '0';
// Add the characters numeric value to the current value
value = (value * 10) + c_value;
// Note the multiplication with 10: That's because decimal numbers are base 10
}
// Now the string have been converted to its decimal integer value, return it
return value;
}
如果我们用字符串 "123"
调用它并展开循环发生的事情是这样的:
// First iteration
char c = string[0]; // c = '1'
int c_value = c - '0'; // c_value = 1
value = (value * 10) + c_value; // value = (0 * 10) + 1 = 0 + 1 = 1
// Second iteration
char c = string[0]; // c = '2'
int c_value = c - '0'; // c_value = 2
value = (value * 10) + c_value; // value = (1 * 10) + 2 = 10 + 2 = 12
// Third iteration
char c = string[0]; // c = '3'
int c_value = c - '0'; // c_value = 3
value = (value * 10) + c_value; // value = (12 * 10) + 3 = 120 + 3 = 123
在第四次迭代中,我们到达字符串 null-terminator 并且循环结束时 value
等于 int
值 123
.
我希望这能让大家更清楚地了解字符串到数字的转换是如何工作的。
虽然上面是字符串,如果你读取现有 int
值的原始二进制位,那么你不应该调用 strtol
因为数据不是字符串。
相反,您基本上将四个字节解释为一个 32 位值。
不幸的是,如果不了解关于 endianness 的一两件事,就很难解释这些位是如何解释的。
字节序是字节组成整数值的方式。采用(十六进制)数字 0x01020304
,它们可以存储为 0x01
、0x02
、0x03
和 0x04
(这称为 big-endian) ; 或如0x04
、0x03
、0x02
和0x01
(这叫little-endian)。
在 little-endian 系统(您的普通 PC-like 系统)上假设您有一个这样的数组:
char bytes[4] = { 0x04, 0x03, 0x02, 0x01 };
然后你可以把它复制到 int
:
int value;
memcpy(&value, bytes, 4);
这将使 int
变量 value
等于 0x01020304
。
I have char array that I read from binary file (like ext2 formatted filesystem image file).
以二进制模式打开文件
const char *file_name = ...;
FILE *infile = fopen(file_name, "rb"); // b is for binary
if (infile == NULL) {
fprintf(stderr, "Unable to open file <%s>.\n", file_name);
exit(1);
}
I need to read integer starting at offset byte 1024 ...
long offset = 1024;
if (fseek(infile, offset, SEEK_SET)) {
fprintf(stderr, "Unable to seek to %ld.\n", offset);
exit(1);
}
So I believe can be represented in integer size of 4 byte on my system
与其使用可能与 4 字节不同的 int
,不如考虑 int32_t
来自 <stdint.h>
。
int32_t data4;
if (fread(&data4, sizeof data4, 1, infile) != 1) {
fprintf(stderr, "Unable to read data.\n");
exit(1);
}
帐户 Endian。
因为文件数据是little-endian, convert to native endian. See #include <endian.h>
.
data4 = le32toh(data4);
完成后清理
// Use data4
fclose(infile);
believe I need to use
strtol
like
没有。 strtol()
检查一个 字符串 和 returns 一个 long
。文件数据是二进制的,不是字符串。