C rewind 函数
最后修改日期:2025 年 4 月 6 日
C 语言中的文件处理需要精确控制文件位置以实现高效的数据访问。rewind 函数将文件位置指示器重置到文件开头。本教程将通过实际示例详细解释 rewind。您将学习何时以及如何有效地在文件操作中使用它。掌握 rewind 有助于在需要重新读取或覆盖文件内容的情况下进行操作。
什么是 rewind?
C 语言中的 rewind 函数将文件位置指示器重置到文件开头。它接受一个参数:指向 FILE 对象的指针。与 fseek 不同,它不返回值,并清除所有错误指示器。它等同于 fseek(fp, 0L, SEEK_SET),但更易于使用。在调用 rewind 之前,请始终确保文件已成功打开。
基本 rewind 示例
此示例演示了 rewind 最简单的用法,即读取文件两次。
#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 数据。
#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 对于二进制文件同样有效,如下所示。
#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 与更新模式结合使用,以实现灵活的文件访问。
#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 比较
比较 rewind 和 fseek 的定位功能。
#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;
}
fseek 和 rewind 都可以移动到文件开头,但 rewind 更简单。fseek 返回一个状态,而 rewind 不返回。rewind 还会清除错误标志。ftell 在每次操作后确认位置。
Rewind 的错误处理
正确的错误处理可确保 rewind 的安全使用。
#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 分块处理大型文件。
#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 的最佳实践
- 检查文件打开状态: 在 rewind 之前,始终验证文件是否成功打开。
- 理解模式: 确保文件以支持寻道(seeking)的模式打开。
- 清除错误: 请记住 rewind 会清除错误指示器,这可能会掩盖问题。
- 结合 flush: 对于写入操作,请考虑在 rewind 前使用 fflush。
- fseek 的替代方法: 当只需要返回文件开头时,请使用 rewind。
来源
本教程展示了 C 语言文件处理中 rewind 的多功能性。从基本的文件重读到错误恢复,rewind 简化了位置管理。正确使用此函数可使文件处理更加健壮和高效。
作者
列表 C 标准库。