我正在编写一个需要逐行解析配置文件的函数。
我基本上有3种方法可以从这里开始,我正处于将内容读入内存的阶段:
读取一行中的字符数量,fseek()
返回行首,malloc()
缓冲区,将行读入内存
读取行中的字符,并为每个添加字符读取realloc()
做出猜测'合理的行长度,一旦超过,则仅realloc()
。
时间在这个阶段并不重要,所以1ms或半秒是不是真的重要,但我希望得到最好的解决方案。
过去我使用过解决方案1,因为我并不是真的想调用realloc()
几百次。
什么是最佳做法?
E /
进一步解释:
我的配置文件看起来像这样
key = value #comment
我在阅读时将=
字符替换为\0
字符并跟踪偏移量。然后我strcompare()
我要查找的行到配置标记,一旦找到匹配的配置标记,我将值移动到数组的开头并进行后处理(atoi()
,{{1那些东西)并把它放到另一个变量中。之后,我释放了我的读取线并转到下一行。
strtoull()
不被读入内存之后,我会跳过空格和所有内容。所以我的整个key = value字符串在99%的情况下都是<64字节。
答案 0 :(得分:2)
不是分配小缓冲区并经常重新分配,而是分配一个大缓冲区并重新分配到所需的确切大小。也许这样的事情会起作用吗?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *getinput ( ) {
char *input;
input = malloc ( 1000); // allocate a large buffer
fgets (input, 1000, stdin);
// may need to set a '\0' somewhere in input...
input = realloc ( input, strlen(input) + 1); // realloc to exact size
return input;
}
int main()
{
char *output[10];
int counter = 0;
while ( counter < 10) {
output[counter] = getinput();
printf ( "%s\n", output[counter]);
counter++;
}
counter = 0;
while ( counter < 10) {
printf ( "\t%s\n", output[counter]);
free ( output[counter]);
counter++;
}
return 0;
}
答案 1 :(得分:1)
当输入数据的大小变大时,我使用类似于Exponential Backoff的技术。
近似算法是:
realloc()
)如果您一次读取整个文件,则只需将所有传入数据附加到缓冲区的末尾。
如果您一次只读一行,请在循环中使用fgets()
,如下所示:
buffer[size - 1] = 0xFF
; fgets(buffer, size, fp);
buffer[size - 1] == '\0'
然后缓冲区已满,realloc()
它并转到第2步当您希望获得任意大行时,这种方法是明智的,例如,有人会决定将一些base64编码的数据放入配置文件中。如果不是这种情况,我通常会尽量保持简单:
abort()
事实上,这种方法往往比任何缓冲区重新分配产生更少的错误,KISS的美丽。
答案 2 :(得分:0)
我会做以下事情:
首先将整个文件读入缓冲区,只需先检查大小即可。 stat()然后全部读完。
将整个文件内容放入缓冲区后,您可以根据自己的内容进行操作。