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 toNULL.reallocacceptsNULLand behaves likemallocwith such as argument,freeaccepts aNULL` 参数,什么也不做。
  • 不要转换 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;
}