考虑以下简单的C程序,该程序将文件读入缓冲区并将该缓冲区显示到控制台:
#includemain() { FILE *file; char *buffer; unsigned long fileLen; //Open file file = fopen("HelloWorld.txt", "rb"); if (!file) { fprintf(stderr, "Unable to open file %s", "HelloWorld.txt"); return; } //Get file length fseek(file, 0, SEEK_END); fileLen=ftell(file); fseek(file, 0, SEEK_SET); //Allocate memory buffer=(char *)malloc(fileLen+1); if (!buffer) { fprintf(stderr, "Memory error!"); fclose(file); return; } //Read file contents into buffer fread(buffer, fileLen, 1, file); //Send buffer contents to stdout printf("%s\n",buffer); fclose(file); }
它将读取的文件只包含:
你好,世界!
输出是:
Hello World!²²²²
已经有一段时间了,因为我在C/C++中做了很多重要事情,但通常我会认为缓冲区的分配大于必要的,但事实并非如此.
fileLen最终为12,这是准确的.
我现在在想,我必须只是显示错误的缓冲区,但我不确定我做错了什么.
谁能让我知道我做错了什么?
你需要NUL终止你的字符串.加
buffer[fileLen] = 0;
在打印之前.
JesperE的方法可行,但您可能有兴趣知道有另一种处理方法.
通过提供长度printf
为字符串字段的精度,您始终可以打印已知长度的字符串,即使没有NUL终止符也是如此:
printf("%.*s\n", fileLen, buffer);
这允许您在不修改缓冲区的情况下打印字符串.
关于你的例子中的nul-termination问题,JesperE是正确的,我只是补充一点,如果你正在处理文本文件,最好使用fgets()或类似的东西,因为这将适当地处理不同平台上的换行序列,并且总是nul-为你终止字符串.如果您真的使用二进制数据,那么您不希望使用printf()输出数据,因为printf函数需要字符串,数据中的空字节将导致输出截断.