我正在尝试学习如何在读取文件时为很长的行动态分配内存。我在这里和网上搜索,我尝试了一些代码。
首先,这是我的第一个非动态代码:
char line[256];
file = fopen(inputFileName, "r");
// Here, of course I checked file is opened or not.
while (fgets(line, sizeof(line), file)) {
// do some operations
}
// Closing operations
当我阅读文件时,这对我有用。但这里的行必须等于或少于255个字符。所以,我想从文件中读取300个字符长度的行。
我尝试了以下代码:
size_t maxl = 256;
//char line[256];
char *line = malloc(maxl * sizeof(char));
if(!line){
printf("Memory not allocated!!\n");
return -2;
}
file = fopen(inputFileName, "r");
while (fgets(line, sizeof(line), file)) {
while(line[strlen(line) - 1] != '\n' || line[strlen(line) - 1] != '\r'){
char *tmp = realloc (line, 2 * maxl);
//fgets(line, sizeof(line), file);
if (tmp) {
line = tmp;
maxl *= 2;
}
else{
printf("Not enough memory for this line!!\n");
return -3;
}
}
// do some operations
}
我试图在这个问题中实现答案:Reading a line from file in C, dynamically
但它总是进入"没有足够的记忆"部分代码。那么,我做错了什么?
非常感谢您的回答和建议。
编辑:代码更新取决于第一条评论。
编辑2:代码始终从文件中读取相同的3个字符。
想象一下,该文件就像:
abcdabcdabcd...
line
变量总是" abc"即使在重新分配操作之后。
答案 0 :(得分:2)
以下是您需要做的一些更正:
char *tmp = realloc (line, 2 * maxl);
更改为char *tmp = realloc (line, 2 * maxl * sizeof(char);
(只是一个建议!)。fseek(file,0,SEEK_SET);
将搜索文件inputFileName
的开头。sizeof(line)
将始终是常量值,因为您正在计算字符指针的大小,而不是字符串长度。因此,请将while (fgets(line, sizeof(line), file)) {
更改为while (fgets(line, maxl, file)) {
。//fgets(line, sizeof(line), file);
移到if (tmp)
块中,因为您需要在重新分配后再次从文件中读取字符串。line[strlen(line) - 1] != '\n' || line[strlen(line) - 1] != '\r'
在逻辑上是不正确的。仅当line
的最后一个字符既不是'\n'
也不是'\r'
时,您可能只想进入循环。因此,您必须使用&&
代替||
。以下是修改后的代码:
size_t maxl = 256;
//char line[256];
char *line = malloc(maxl * sizeof(char));
if(!line){
printf("Memory not allocated!!\n");
return -2;
}
file = fopen(inputFileName, "r");
while (fgets(line, maxl, file)) {
while(line[strlen(line) - 1] != '\n' && line[strlen(line) - 1] != '\r'){
char *tmp = realloc (line, 2 * maxl * sizeof(char));
fseek(file,0,SEEK_SET); //or wherever you want to seek to
if (tmp) {
line = tmp;
maxl *= 2;
fgets(line, maxl, file);
}
else{
printf("Not enough memory for this line!!\n");
return -3;
}
}
printf("%s\n",line); //just to check
}
代码中的问题是:
sizeof(line)
个字符数而不是maxl
个字符数。if(tmp)
)。现在,为什么Not enough memory..
正在打印?
这是因为你的循环运行了多次,重新分配的内存大小(maxl
值)增加了,如256,512,1024,2048,...,65536,......
当此大小变得足够大以使编译器拒绝重新分配时,您打印了该错误字符串。如果您愿意,请尝试调试您的代码版本,或在内部maxl
循环的每次迭代中打印while
的值。