fread 位置光标似乎没有按预期前进
fread position cursor does not seem to advance as expected
我正在尝试动态地 realloc
内存以一次读取一个字符的文件。它不是逐个字符地打印缓冲区。看起来 fread
函数不是一次前进 1 个字符。
int main() {
FILE *fp;
char *newBuffer;
char *buffer = malloc(sizeof(char));
int count = 0;
/* Open file for both reading and writing */
fp = fopen("test.txt", "r");
if (!fp) {
exit(99);
}
/* Seek to the beginning of the file */
fseek(fp, SEEK_SET, 0);
/* Read into memory and display the buffer as its read */
while (1) {
newBuffer = (char*)realloc(buffer, (sizeof(char) * (++count)));
if (newBuffer) {
buffer = newBuffer;
buffer += (count - 1);
fread(buffer, sizeof(char), 1, fp);
if (feof(fp)) {
buffer = newBuffer;
break;
}
buffer = newBuffer;
printf(" %s\n", buffer);
} else {
// realloc failed
free(buffer);
exit(1);
}
}
fclose(fp);
free(newBuffer);
return(0);
}
您的 printf(" %s\n", buffer);
期望 buffer
以 '[=12=]'
(空)字符结尾。您的代码未提供所需的 null。
在 printf
中将缓冲区用作字符串之前不要空终止缓冲区,这是一个问题。
请注意,您可以通过多种方式简化或改进代码:
fopen
后无需fseek(fp, SEEK_SET, 0);
,FILE已经在起始位置。请注意,您将参数反转为 fseek
:它应该是 fseek(fp, 0L, SEEK_SET);
但您很幸运 SEEK_SET
被#defined 为 0
.
- 使用
getc
从文件中读取一个字节比使用 fread(buffer, sizeof(char), 1, fp);
简单得多。它允许对文件结尾进行更简单和更好的测试。使用 feof()
仅适用于您的示例,因为您只尝试读取一个字节。
- 不需要初始
malloc
,设置buffer to
NULL.
reallocaccepts
NULLand behaves like
mallocwith such as argument,
freeaccepts a
NULL` 参数,什么也不做。
- 不要转换
malloc
的 return 值,也不要转换 realloc
。
sizeof(char)
根据定义是 1
:使用 sizeof(*buffer)
或完全省略 sizeof。
- 不要将
return
表达式括起来。
- 没有参数的
main
的原型是 int main(void)
这是一个更简单的版本:
int main(void) {
FILE *fp;
char *newBuffer;
char *buffer = NULL;
int count = 0, c;
/* Open file for both reading */
fp = fopen("test.txt", "r");
if (!fp) {
exit(99);
}
/* Read into memory and display the buffer read */
while ((c = getc(fp)) != EOF) {
newBuffer = realloc(buffer, count + 2);
if (newBuffer) {
buffer = newBuffer;
buffer[count++] = c;
buffer[count] = '[=10=]';
printf(" %s\n", buffer);
} else {
// realloc failed
fclose(fp);
free(buffer);
exit(1);
}
}
fclose(fp);
free(buffer);
return 0;
}
我正在尝试动态地 realloc
内存以一次读取一个字符的文件。它不是逐个字符地打印缓冲区。看起来 fread
函数不是一次前进 1 个字符。
int main() {
FILE *fp;
char *newBuffer;
char *buffer = malloc(sizeof(char));
int count = 0;
/* Open file for both reading and writing */
fp = fopen("test.txt", "r");
if (!fp) {
exit(99);
}
/* Seek to the beginning of the file */
fseek(fp, SEEK_SET, 0);
/* Read into memory and display the buffer as its read */
while (1) {
newBuffer = (char*)realloc(buffer, (sizeof(char) * (++count)));
if (newBuffer) {
buffer = newBuffer;
buffer += (count - 1);
fread(buffer, sizeof(char), 1, fp);
if (feof(fp)) {
buffer = newBuffer;
break;
}
buffer = newBuffer;
printf(" %s\n", buffer);
} else {
// realloc failed
free(buffer);
exit(1);
}
}
fclose(fp);
free(newBuffer);
return(0);
}
您的 printf(" %s\n", buffer);
期望 buffer
以 '[=12=]'
(空)字符结尾。您的代码未提供所需的 null。
在 printf
中将缓冲区用作字符串之前不要空终止缓冲区,这是一个问题。
请注意,您可以通过多种方式简化或改进代码:
fopen
后无需fseek(fp, SEEK_SET, 0);
,FILE已经在起始位置。请注意,您将参数反转为fseek
:它应该是fseek(fp, 0L, SEEK_SET);
但您很幸运SEEK_SET
被#defined 为0
.- 使用
getc
从文件中读取一个字节比使用fread(buffer, sizeof(char), 1, fp);
简单得多。它允许对文件结尾进行更简单和更好的测试。使用feof()
仅适用于您的示例,因为您只尝试读取一个字节。 - 不需要初始
malloc
,设置buffer to
NULL.
reallocaccepts
NULLand behaves like
mallocwith such as argument,
freeaccepts a
NULL` 参数,什么也不做。 - 不要转换
malloc
的 return 值,也不要转换realloc
。 sizeof(char)
根据定义是1
:使用sizeof(*buffer)
或完全省略 sizeof。- 不要将
return
表达式括起来。 - 没有参数的
main
的原型是int main(void)
这是一个更简单的版本:
int main(void) {
FILE *fp;
char *newBuffer;
char *buffer = NULL;
int count = 0, c;
/* Open file for both reading */
fp = fopen("test.txt", "r");
if (!fp) {
exit(99);
}
/* Read into memory and display the buffer read */
while ((c = getc(fp)) != EOF) {
newBuffer = realloc(buffer, count + 2);
if (newBuffer) {
buffer = newBuffer;
buffer[count++] = c;
buffer[count] = '[=10=]';
printf(" %s\n", buffer);
} else {
// realloc failed
fclose(fp);
free(buffer);
exit(1);
}
}
fclose(fp);
free(buffer);
return 0;
}