如何从 C 中的二进制文件中读取插入符号?

How to read caret notations from a binary file in C?

我有一个需求,每次一个字节读取二进制文件中的字符,并在满足特定条件时将它们连接起来。我 运行 在读取空字符时遇到问题,即 ^@,如插入符符号中所示。 snprintf 和 strcpy 都没有帮助我将这个空字符与其他字符连接起来。这很奇怪,因为当我使用

打印这个字符时
printf("%c",char1);

它打印出插入符号中的空字符,即 ^@。所以我的理解是连snprintf都应该拼接成功了

谁能告诉我如何实现这样的串联?

谢谢

C 字符串以 null 结尾。如果您的输入数据可以包含空字节,则您无法安全地使用字符串函数。相反,考虑只分配一个足够大的缓冲区(或根据需要动态调整它的大小)并将每个传入字节写入该缓冲区中的正确位置。

由于您不使用原始 ANSI 字符串,因此不能使用旨在与原始 ANSI 字符串一起使用的函数,因为解释字符串的方式。

在 C(和 C++)中,字符串通常以 null 结尾,即最后一个字符是 [=14=](值 0x00)。至少对于字符串操作和 input/ouput(如 printf()strcpy())的标准函数来说是这样。

例如,行

const char *text = "Hello World";

幕后变成

const char *text = "Hello World[=11=]";

因此,当您从文件中读取 [=14=] 并将其放入您的字符串时,您最终得到的实际上是一个空字符串。

为了让问题更清楚,举个简单的例子:

// Let's just assume the sequence 0x00, 0x01 is some special encoding
const char *input = "Hello[=12=]World!";
char output[256];

strcpy(output, input);
// strncpy() is for string manipulation, as such it will stop once it encounters a null terminator

printf("%s\n", output); // This will print 'Hello'

memcpy(output, input, 14); // 14 is the string length above plus null terminator

printf("%s\n", output); // This will again print 'Hello' (since it stops at the terminator)

printf("%s\n", output + 7); // This will print "World" (you're skipping the terminator using the offset)

以下是我整理的一个简单示例。它不一定显示最佳实践,也可能存在一些错误,但它应该向您展示一些可能的概念,如何使用原始字节数据,尽可能避免使用标准字符串函数。

#include <stdio.h>

#define WIDTH 16

int main (int argc, char **argv) {
    int offset = 0;
    FILE *fp;
    int byte;
    char buffer[WIDTH] = ""; // This buffer will store the data read, essentially concatenating it

    if (argc < 2)
        return 1;

    if (fp = fopen(argv[1], "rb")) {
        for(;;) {
            byte = fgetc(fp); // get the next byte

            if (byte == EOF) { // did we read over the end of the file?
                if (offset % WIDTH)
                    printf("%*s %*.*s", 3 * (WIDTH - offset % WIDTH), "", offset % WIDTH, offset % WIDTH, buffer);
                else
                    printf("\n");
                return 0;
            }

            if (offset % WIDTH == 0) { // should we print the offset?
                if (offset)
                    printf(" %*.*s", WIDTH, WIDTH, buffer); // print the char representation of the last line
                printf("\n0x%08x", offset);
            }

            // print the hex representation of the current byte
            printf(" %02x", byte);

            // add printable characters to our buffer
            if (byte >= ' ')
                buffer[offset % WIDTH] = byte;
            else
                buffer[offset % WIDTH] = '.';

            // move the offset
            ++offset;
        }
        fclose(fp);
    }
    return 0;
}

编译后,将任何文件作为第一个参数传递以查看其内容(不应太大以免破坏格式)。