字符阵列中的字节如何代表整数?

发布于 2025-01-26 02:04:36 字数 548 浏览 3 评论 0原文

因此,假设我有从二进制文件中读取的char数组(例如Ext2格式的文件系统图像文件)。

现在,我需要阅读从Offset Byte 1024(< - 这是数据开始的偏移)开始的整数。是否有任何整洁的方法。整数可能是任何数字。因此,我相信我的系统上可以以4个字节的整数大小表示(x86-64)。

我相信我需要使用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是否应该终止?

这是正确的吗?

So let's say I have char array that I read from binary file (like ext2 formatted filesystem image file).

Now I need to read integer starting at offset byte 1024(<--that's the offset from start of data). Is there any neat way of doing it. The integer could be any number. So I believe can be represented in integer size of 4 byte on my system (x86-64).

I believe I need to use strtol like:

/* 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);

The above is long so is this the number to represent a integer 32 bit?

Should eptr be null terminated?

Is this correct or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

够运 2025-02-02 02:04:36

我有从二进制文件中读取的char数组(例如 ext2 格式)。

以二进制模式打开文件

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);
}

我需要阅读从偏移时开始的整数。

long offset = 1024; 
if (fseek(infile, offset, SEEK_SET)) {
  fprintf(stderr, "Unable to seek to %ld.\n", offset);
  exit(1);
} 

所以我相信可以在我的系统上以4个字节的整数大小表示

而不是使用int,这可能与4个字样不同,请考虑&lt; stdint.h&gt;

int32_t data4;
if (fread(&data4, sizeof data4, 1, infile) != 1) {
  fprintf(stderr, "Unable to read data.\n");
  exit(1);
} 

帐户 endian

因为文件数据为 litty-endian> little-endian ,转换为本地endian。参见 #include&lt&lt; endian.h&gt;

data4 = le32toh(data4);

完成后清理

// Use data4

fclose(infile);

相信我需要使用strtol喜欢

strtol()检查A String 并返回long。文件数据是二进制的,而不是字符串。

I have char array that I read from binary file (like ext2 formatted filesystem image file).

Open the file in binary mode

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

Rather than use int, which may differ from 4-bytes, consider int32_t from <stdint.h>.

int32_t data4;
if (fread(&data4, sizeof data4, 1, infile) != 1) {
  fprintf(stderr, "Unable to read data.\n");
  exit(1);
} 

Account for Endian.

As file data is little-endian, convert to native endian. See #include <endian.h>.

data4 = le32toh(data4);

Clean up when done

// Use data4

fclose(infile);

believe I need to use strtol like

No. strtol() examines a string and returns a long. File data is binary and not a string.

安穩 2025-02-02 02:04:36

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] != '\0'; ++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末端和循环以value等于int value 123等于。

我希望这使得字符串转换如何工作更清楚。


虽然以上是字符串,但如果您读取现有int值的原始二进制位,则不应调用strtol,因为数据不是字符串。

相反,您基本上将四个字节解释为一个32位值。

不幸的是,在不知道关于

endianness是命令字节组成整数值的方式。服用(十六进制)编号0x01020304可以将它们存储为0x010x020x030x04(这称为big-endian); 作为0x040x030x020x01 endian)。

在一个小型系统(您的普通PC状系统)上说您有这样的数组:

char bytes[4] = { 0x04, 0x03, 0x02, 0x01 };

然后,您可以将其复制到int

int value;
memcpy(&value, bytes, 4);

这将使int变量等于0x01020304

In the case of strtol it might be easier to follow along by seeing some code. So here a very simplified strtol kind of function:

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] != '\0'; ++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;
}

If we call it with the string "123" and unroll the loop what's happening is this:

// 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

In the fourth iteration we reach the string null-terminator and the loop ends with value being equal to the int value 123.

I hope this makes it a little clearer about how string to number conversions are working.


While the above is for strings, if you read the raw binary bits of an existing int value, then you should not call strtol because the data isn't a string.

Instead you basically interpret the four bytes as a single 32-bit value.

Unfortunately it's not easy to explain how these bits are interpreted without knowing a thing or two about endianness.

Endianness is how the bytes are ordered to make up the integer value. Taking the (hexadecimal) number 0x01020304 they can be stored either as 0x01, 0x02, 0x03 and 0x04 (this is called big-endian); Or as 0x04, 0x03, 0x02 and 0x01 (this is called little-endian).

On a little-endian system (your normal PC-like system) say you have an array like this:

char bytes[4] = { 0x04, 0x03, 0x02, 0x01 };

then you could copy it into an int:

int value;
memcpy(&value, bytes, 4);

and that will make the int variable value equal to 0x01020304.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文