我想将文件的全部内容写入缓冲区.该文件实际上只包含一个我需要与字符串进行比较的字符串.
什么是最有效的选项,即使在Linux上也可以移植.
ENV:Windows
小智 140
Linux和Windows之间的可移植性是一个令人头痛的问题,因为Linux是一个符合POSIX标准的系统,通常是一个适当的,高质量的C工具链,而Windows甚至不提供C标准库中的许多功能.
但是,如果你想坚持标准,你可以这样写:
#include <stdio.h>
#include <stdlib.h>
FILE *f = fopen("textfile.txt", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET); /* same as rewind(f); */
char *string = malloc(fsize + 1);
fread(string, 1, fsize, f);
fclose(f);
string[fsize] = 0;
Run Code Online (Sandbox Code Playgroud)
这里string将包含文本文件的内容作为正确的0终止的C字符串.这段代码只是标准的C,它不是特定于POSIX的(尽管它不保证它可以在Windows上工作/编译......)
Nom*_*mal 18
这是我推荐的.
它应该符合C89,并且完全可移植.特别是,它也适用于POSIXy系统上的管道和插座.
我们的想法是,我们以大容量chunks(READALL_CHUNK)读取输入,根据需要动态地重新分配缓冲区.我们只使用realloc(),fread(),ferror(),和free():
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
/* Size of each input chunk to be
read and allocate for. */
#ifndef READALL_CHUNK
#define READALL_CHUNK 262144
#endif
#define READALL_OK 0 /* Success */
#define READALL_INVALID -1 /* Invalid parameters */
#define READALL_ERROR -2 /* Stream error */
#define READALL_TOOMUCH -3 /* Too much input */
#define READALL_NOMEM -4 /* Out of memory */
/* This function returns one of the READALL_ constants above.
If the return value is zero == READALL_OK, then:
(*dataptr) points to a dynamically allocated buffer, with
(*sizeptr) chars read from the file.
The buffer is allocated for one extra char, which is NUL,
and automatically appended after the data.
Initial values of (*dataptr) and (*sizeptr) are ignored.
*/
int readall(FILE *in, char **dataptr, size_t *sizeptr)
{
char *data = NULL, *temp;
size_t size = 0;
size_t used = 0;
size_t n;
/* None of the parameters can be NULL. */
if (in == NULL || dataptr == NULL || sizeptr == NULL)
return READALL_INVALID;
/* A read error already occurred? */
if (ferror(in))
return READALL_ERROR;
while (1) {
if (used + READALL_CHUNK + 1 > size) {
size = used + READALL_CHUNK + 1;
/* Overflow check. Some ANSI C compilers
may optimize this away, though. */
if (size <= used) {
free(data);
return READALL_TOOMUCH;
}
temp = realloc(data, size);
if (temp == NULL) {
free(data);
return READALL_NOMEM;
}
data = temp;
}
n = fread(data + used, 1, READALL_CHUNK, in);
if (n == 0)
break;
used += n;
}
if (ferror(in)) {
free(data);
return READALL_ERROR;
}
temp = realloc(data, used + 1);
if (temp == NULL) {
free(data);
return READALL_NOMEM;
}
data = temp;
data[used] = '\0';
*dataptr = data;
*sizeptr = used;
return READALL_OK;
}
Run Code Online (Sandbox Code Playgroud)
上面,我使用了一个恒定的块大小,READALL_CHUNK== 262144(256*1024).这意味着在最坏的情况下,浪费了多达262145个字符(已分配但未使用),但只是暂时的.最后,该函数将缓冲区重新分配到最佳大小.此外,这意味着我们每兆字节读取数据会进行四次重新分配.
上面代码中的262144字节默认值是保守值; 它适用于老式的minilaptops和Raspberry Pis以及大多数嵌入式设备,至少有几兆字节的RAM可用于此过程.然而,它并不是那么小,以至于它在大多数系统上减慢了操作(由于许多读取调用和许多缓冲区重新分配).
对于目前(2017年)的台式机,我建议更大READALL_CHUNK,也许#define READALL_CHUNK 2097152(2 MiB).
因为保护定义READALL_CHUNK(即,只有在代码中的那一点仍然未定义时才定义),您可以在编译时覆盖默认值,通过使用(在大多数C编译器中)-DREADALL_CHUNK=2097152命令行选项 -但请检查您的编译器选项,以使用命令行选项定义预处理器宏.
| 归档时间: |
|
| 查看次数: |
167470 次 |
| 最近记录: |