关于 printf 中的字符串

Regarding strings in printf

由此post

FILE *fileptr;
char *buffer;
long filelen;

fileptr = fopen("myfile.txt", "rb");  // Open the file in binary mode
fseek(fileptr, 0, SEEK_END);          // Jump to the end of the file
filelen = ftell(fileptr);             // Get the current byte offset 
                                         in the file
rewind(fileptr);                      // Jump back to the beginning of 
                                         the file

buffer = (char *)malloc((filelen+1)*sizeof(char)); // Enough memory 
                                                      for file + [=10=]
fread(buffer, filelen, 1, fileptr); // Read in the entire file
fclose(fileptr); // Close the file

您将文件读取为字节数组。

很明显,它只是一个字符串。 可以添加一个

buffer[filelen] = '[=11=]';

printf("%s" , buffer);

应该像打印字符串一样打印文件的全部内容。它在简单的文本文件中这样做,但在二进制文件中不这样做。

对于二进制文件,必须编写如下函数:

void traverse(char *string ,size_t size){
  for(size_t i=0;i<size;i++)
    printf("%c",string[i]);
}

并逐一打印每个字符。 这会在屏幕上显示乱码。

对于第二个要点,我知道这可能是由于 signed char 但即使字符串存储为 unsigned char 结果仍然相同。

这里的第一个问题是您混淆了读取文件的目的。要从文件中读取 binary 数据,并随后打印该二进制数据,您应该始终使用 unsigned charunsigned char* 来存储从 二进制文件。

这是因为为了准确表示打印的数据,您需要在 printf 的格式字符串中使用 "%u" 类型标志。根据 ASCII 仅 some characters are printable,这意味着如果您希望查看文件中的所有二进制数据,如果您使用 "%c" 标志,您将无法看到其中的一些打印出来。

你的函数的二进制版本是:

void traverse(unsigned char *string ,size_t size){
  for(size_t i=0;i<size;i++)
    printf("%u",string[i]);
}

第二期是

should print the entrire contents of a file as if it were a string. And it does so in simple text files but not in binary ones.

这不是真的。使用 "%s" 标志打印字符,就好像它们是可打印字符一样,它会在到达空值时终止,[=17=] 字符。您无法有效地使用 %s 来打印二进制数据。

Why printf doesn't treat buffer as a character string incase of binary files?

printf("%s",buffer) 是否 假定 buffer 包含 C 字符串。问题是,那不是 buffer 实际包含的内容。您的 buffer 实际上包含二进制文件中的字节。

C 字符串以第一个零字节(a.k.a., '\0', a.k.a., ASCII NUL)和任意非文本文件(a.k.a., "binary file") 可以在其自身的任何位置包含零字节。 printf "%s" 格式将在看到第一个零字节后立即停止。

Why printf in function traverse puts gibberish instead of characters?

即"gibberish"个字符。但是这些字符没有任何意义,因为您试图解释为字符序列的文件不应该以这种方式解释。

文本文件是一个字节序列,旨在根据某些 character encoding 呈现,通常 旨在传达某种人类可读的信息。任意 "binary" 文件可能包含一系列不应代表人类可读文本的字节。它们代表其他东西,某些计算机程序可以理解。

printf "%s" 尝试 根据某些字符编码系统(通常 UTF-8 or US-ASCII)呈现这些字节,但是 (a) 它不会'并不总是能够这样做,并且 (b) 即使 能够这样做,字符序列也没有任何意义。