ZetCode

C rewind 函数

最后修改日期:2025 年 4 月 6 日

C 语言中的文件处理需要精确控制文件位置以实现高效的数据访问。rewind 函数将文件位置指示器重置到文件开头。本教程将通过实际示例详细解释 rewind。您将学习何时以及如何有效地在文件操作中使用它。掌握 rewind 有助于在需要重新读取或覆盖文件内容的情况下进行操作。

什么是 rewind?

C 语言中的 rewind 函数将文件位置指示器重置到文件开头。它接受一个参数:指向 FILE 对象的指针。与 fseek 不同,它不返回值,并清除所有错误指示器。它等同于 fseek(fp, 0L, SEEK_SET),但更易于使用。在调用 rewind 之前,请始终确保文件已成功打开。

基本 rewind 示例

此示例演示了 rewind 最简单的用法,即读取文件两次。

basic_rewind.c
#include <stdio.h>

int main() {
    FILE *fp = fopen("data.txt", "r");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    // First read
    printf("First read:\n");
    char ch;
    while ((ch = fgetc(fp)) != EOF) {
        putchar(ch);
    }

    rewind(fp);  // Reset to beginning

    // Second read
    printf("\n\nSecond read:\n");
    while ((ch = fgetc(fp)) != EOF) {
        putchar(ch);
    }

    fclose(fp);
    return 0;
}

此程序打开一个文件并读取其内容两次。第一次读取后,rewind 将位置重置到开头。如果没有 rewind,第二次读取将失败,因为指针将位于 EOF。在两次读取完成后,文件会被正确关闭。

写入后 rewind

使用 rewind 来读取您刚刚写入文件的back 数据。

rewind_after_write.c
#include <stdio.h>

int main() {
    FILE *fp = fopen("temp.txt", "w+");
    if (fp == NULL) {
        perror("Error creating file");
        return 1;
    }

    fprintf(fp, "Sample text\n");  // Write to file
    rewind(fp);  // Go back to start

    char buffer[50];
    fgets(buffer, sizeof(buffer), fp);  // Read what we wrote
    printf("File content: %s", buffer);

    fclose(fp);
    remove("temp.txt");  // Clean up
    return 0;
}

此示例使用 "w+" 模式来写入和读取文件。写入后,rewind 允许从开头读取。临时文件在使用后会被删除。这种模式对于临时数据处理很有用。

二进制文件 rewind

rewind 对于二进制文件同样有效,如下所示。

binary_rewind.c
#include <stdio.h>

int main() {
    FILE *fp = fopen("data.bin", "wb+");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    int nums[] = {1, 2, 3, 4, 5};
    fwrite(nums, sizeof(int), 5, fp);  // Write array

    rewind(fp);  // Back to start

    int read_nums[5];
    fread(read_nums, sizeof(int), 5, fp);  // Read array
    for (int i = 0; i < 5; i++) {
        printf("%d ", read_nums[i]);
    }

    fclose(fp);
    return 0;
}

此程序将一个整数数组写入二进制文件,然后使用 rewind 将其读回。二进制模式 ("wb+") 可确保精确的数据表示。重置后,数组会成功读取并打印。

更新模式下的 rewind

rewind 与更新模式结合使用,以实现灵活的文件访问。

update_mode.c
#include <stdio.h>

int main() {
    FILE *fp = fopen("data.txt", "r+");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    // Read first line
    char line[100];
    fgets(line, sizeof(line), fp);
    printf("First line: %s", line);

    rewind(fp);  // Back to start

    // Overwrite first line
    fprintf(fp, "New first line\n");

    rewind(fp);  // Read again
    fgets(line, sizeof(line), fp);
    printf("Updated first line: %s", line);

    fclose(fp);
    return 0;
}

"r+" 模式允许读写。读取第一行后,rewind 将我们定位到覆盖它。另一个 rewind 允许我们验证更改。这演示了就地文件修改。

Rewind 与 fseek 比较

比较 rewindfseek 的定位功能。

rewind_vs_fseek.c
#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    // Using fseek to go to start
    fseek(fp, 0L, SEEK_SET);
    printf("Position after fseek: %ld\n", ftell(fp));

    // Using rewind
    rewind(fp);
    printf("Position after rewind: %ld\n", ftell(fp));

    fclose(fp);
    return 0;
}

fseekrewind 都可以移动到文件开头,但 rewind 更简单。fseek 返回一个状态,而 rewind 不返回。rewind 还会清除错误标志。ftell 在每次操作后确认位置。

Rewind 的错误处理

正确的错误处理可确保 rewind 的安全使用。

error_handling.c
#include <stdio.h>

int main() {
    FILE *fp = fopen("nonexistent.txt", "r");
    if (fp == NULL) {
        perror("Initial open failed");
        return 1;
    }

    // Simulate error
    if (fseek(fp, 1000L, SEEK_SET) != 0) {
        perror("fseek failed");
    }

    rewind(fp);  // Clears error and resets position
    printf("Rewind successful\n");

    char ch = fgetc(fp);  // Now works
    printf("First char: %c\n", ch);

    fclose(fp);
    return 0;
}

此示例显示了 rewind 如何从错误状况中恢复。在 fseek 失败后,rewind 会重置位置和错误状态。后续操作将正常工作。始终检查文件操作是否存在错误。

Rewind 在大型文件处理中的应用

使用 rewind 分块处理大型文件。

large_file.c
#include <stdio.h>

#define CHUNK_SIZE 1024

int main() {
    FILE *fp = fopen("large.bin", "rb");
    if (fp == NULL) {
        perror("Error opening file");
        return 1;
    }

    unsigned char buffer[CHUNK_SIZE];
    size_t bytes_read;
    int chunks = 0;

    while ((bytes_read = fread(buffer, 1, CHUNK_SIZE, fp))) {
        chunks++;
        // Process chunk here
        
        if (chunks % 100 == 0) {
            printf("Processed %d chunks\n", chunks);
            rewind(fp);  // Restart processing (demo only)
            break;
        }
    }

    fclose(fp);
    return 0;
}

这演示了分块处理文件。虽然在实际处理循环中通常不会使用 rewind,但它展示了如何重新开始读取。对于实际的大型文件,请考虑内存映射或更复杂的方法。

使用 rewind 的最佳实践

来源

C rewind 文档

本教程展示了 C 语言文件处理中 rewind 的多功能性。从基本的文件重读到错误恢复,rewind 简化了位置管理。正确使用此函数可使文件处理更加健壮和高效。

作者

我叫 Jan Bodnar,是一名敬业的程序员,对编码充满热情。自 2007 年以来,我通过 1,400 多篇文章和 8 本电子书分享我的专业知识。凭借十多年的教学经验,我致力于让编程变得易于理解且引人入胜。

列表 C 标准库