P75 C语言文件操作相关函数大全

fgetc

在C语言中,fgetc 是一个标准库函数,用于从指定的流(通常是文件或标准输入/输出流)中读取一个字符。这个函数在 <stdio.h> 头文件中定义。

函数原型

int fgetc(FILE *stream);

参数

  • stream:一个指向 FILE 对象的指针,该对象标识了要从中读取字符的流。

返回值

  • 如果成功,fgetc 函数返回读取的字符(作为 unsigned char 类型被提升为 int)。
  • 如果遇到文件结束(EOF),则返回 EOF(通常是 -1,但在 <stdio.h> 中定义为一个负数常量)。
  • 如果发生错误,也返回 EOF

注意事项

  • fgetc 函数只读取一个字符。如果你想要读取一行或更多的字符,你需要在一个循环中多次调用它。
  • 读取的字符不会自动转换为字符串(即,它后面不会自动添加空字符 '\0')。
  • 当你使用 fgetc 读取到文件末尾时,它会返回 EOF,并且之后的 fgetc 调用也会继续返回 EOF,除非你重新定位了文件指针(例如,使用 rewind 函数)。

示例

以下是一个简单的示例,展示了如何使用 fgetc 函数从标准输入中读取字符,直到遇到换行符或文件结束:

#include <stdio.h>
int main() {
int ch;
printf("Enter some characters (type Enter to stop):\n");
while ((ch = fgetc(stdin)) != EOF && ch != '\n') {
putchar(ch); // 直接输出读取的字符
}
if (ch == EOF) {
printf("End of file reached.\n");
} else {
printf("Newline character reached.\n");
}
return 0;
}

在这个示例中,fgetc 函数被用于从标准输入(stdin)中读取字符,并在遇到换行符(\n)或文件结束(EOF)时停止。读取的字符直接通过 putchar 函数输出到标准输出。

fputc

在C语言中,fputc 是一个标准库函数,用于将一个字符写入到指定的文件流中。该函数在 <stdio.h> 头文件中定义。

函数原型

int fputc(int character, FILE *stream);

参数

  • character:要写入文件的字符。尽管参数被声明为 int 类型,但实际上只使用它的低8位,即作为一个无符号字符(unsigned char)来处理。
  • stream:指向 FILE 对象的指针,该对象标识了要写入字符的文件流。这通常是通过调用 fopen 函数打开的文件。

返回值

  • 如果写入成功,fputc 函数返回写入的字符(作为 unsigned char 类型被提升为 int)。
  • 如果发生错误,返回 EOF(在 <stdio.h> 中定义的宏,通常是一个负数)。

注意事项

  • 当成功写入一个字符或一个字节的数据后,文件内部写指针会自动后移一个字节的位置。
  • 如果在写入字符之前文件流就已经结束(EOF),或者写入时发生错误,fputc 会返回 EOF

示例

以下是一个简单的示例,展示了如何使用 fputc 函数将一个字符写入到一个文件中:

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "w"); // 打开文件以写入("w" 模式)
if (file == NULL) {
perror("Error opening file");
return 1;
}
char c = 'A';
int result = fputc(c, file); // 将字符 'A' 写入文件
if (result == EOF) {
perror("Error writing to file");
} else {
printf("Character '%c' written successfully.\n", c);
}
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们首先打开一个名为 "example.txt" 的文件以写入模式("w")。然后,我们使用 fputc 函数将一个字符 'A' 写入文件。如果写入成功,我们打印一条消息;如果发生错误,我们打印错误消息并返回。最后,我们关闭文件以确保所有的数据都被正确写入并释放了与文件关联的资源。

fgets

在C语言中,fgets 是一个标准库函数,用于从指定的流(通常是文件或标准输入/输出流)中读取一行,并将其存储在提供的字符串中。这个函数在 <stdio.h> 头文件中定义。

函数原型

char *fgets(char *str, int n, FILE *stream);

参数

  • str:一个指向字符数组的指针,该数组将用于存储从流中读取的字符串。
  • n:指定了最多要读取的字符数(包括最后的空字符 \0)。通常,你会传递数组的大小作为这个参数,以防止缓冲区溢出。
  • stream:一个指向 FILE 对象的指针,该对象标识了要从中读取字符的流。

返回值

  • 如果成功,fgets 函数返回一个指向传入的 str 参数的指针。
  • 如果遇到文件结束(EOF)或发生错误,返回 NULL

注意事项

  • fgets 函数会读取直到遇到换行符(\n)、文件结束符(EOF)或读取了 n-1 个字符为止(然后添加一个空字符 \0 以标记字符串的结束)。
  • 如果在读取任何字符之前就已经遇到了文件结束符或错误,则 str 的内容将保持不变。
  • 如果读取的字符串包含换行符,那么换行符也会被包含在字符串中。

示例

以下是一个简单的示例,展示了如何使用 fgets 函数从标准输入中读取一行文本:

#include <stdio.h>
int main() {
char line[100];
printf("Enter a line of text: ");
if (fgets(line, sizeof(line), stdin) != NULL) {
printf("You entered: %s", line);
} else {
printf("An error occurred while reading the line.\n");
}
return 0;
}

在这个示例中,我们声明了一个字符数组 line,用于存储从标准输入(stdin)读取的字符串。我们使用 fgets 函数来读取一行文本,并将其存储在 line 数组中。然后,我们检查 fgets 的返回值以确保读取成功,并打印出读取的字符串。如果发生错误,我们打印出相应的错误消息。

fputs

在C语言中,fputs 是一个标准库函数,用于将一个字符串写入到指定的文件流中。这个函数在 <stdio.h> 头文件中定义。

函数原型

int fputs(const char *str, FILE *stream);

参数

  • str:一个指向要写入文件的字符串的指针。
  • stream:一个指向 FILE 对象的指针,该对象标识了要写入字符串的文件流。

返回值

  • 如果成功,fputs 函数返回非负值。
  • 如果发生错误,返回 EOF(通常是 -1)。

注意事项

  • fputs 函数会将字符串 str(包括其结尾的空字符 \0 之前的所有字符)写入到指定的文件流中。但是,请注意,fputs 不会在写入的字符串后自动添加一个换行符。如果需要换行,你需要在原始字符串中包含一个换行符,或者在调用 fputs 后使用 fputc('\n', stream); 添加一个。
  • 如果在写入字符串之前文件流就已经结束(EOF),或者写入时发生错误,fputs 会返回 EOF

示例

以下是一个简单的示例,展示了如何使用 fputs 函数将一个字符串写入到一个文件中:

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "w"); // 打开文件以写入("w" 模式)
if (file == NULL) {
perror("Error opening file");
return 1;
}
const char *str = "Hello, World!\n";
int result = fputs(str, file); // 将字符串写入文件
if (result == EOF) {
perror("Error writing to file");
} else {
printf("String written successfully.\n");
}
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们首先打开一个名为 "example.txt" 的文件以写入模式("w")。然后,我们定义了一个字符串 str,并使用 fputs 函数将其写入文件。如果写入成功,我们打印一条消息;如果发生错误,我们打印错误消息并返回。最后,我们关闭文件以确保所有的数据都被正确写入并释放了与文件关联的资源。

fscanf

在C语言中,fscanf 是一个标准库函数,用于从指定的文件流中读取格式化输入。这个函数在 <stdio.h> 头文件中定义,并允许你使用与 printf 类似的格式字符串来指定输入数据的格式。

函数原型

int fscanf(FILE *stream, const char *format, ...);

参数

  • stream:一个指向 FILE 对象的指针,该对象标识了要从中读取数据的文件流。
  • format:一个格式字符串,指定了读取数据的格式。
  • ...:根据格式字符串的要求,这里可以有多个额外的参数,用于存储读取的数据。

返回值

  • 如果成功,fscanf 函数返回成功读取并赋值的输入项数。
  • 如果遇到文件结束(EOF)或发生错误,返回 EOF(通常是 -1)。

注意事项

  • fscanf 函数根据格式字符串从文件流中读取数据,并将这些数据存储在提供的变量中。
  • 格式字符串中的转换说明符(如 %d%f%s 等)用于指定要读取的数据类型。
  • 如果 fscanf 在读取任何数据之前就已经遇到了文件结束符或错误,它将返回 EOF
  • 读取的数据可能会受到空格、制表符和换行符的影响,具体取决于格式字符串中的空白字符(如果有的话)。

示例

以下是一个简单的示例,展示了如何使用 fscanf 函数从一个文件中读取整数和字符串:

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r"); // 打开文件以读取("r" 模式)
if (file == NULL) {
perror("Error opening file");
return 1;
}
int num;
char str[50];
// 假设 example.txt 文件中的内容是 "123 Hello, World!"
if (fscanf(file, "%d %s", &num, str) == 2) {
printf("Read an integer: %d and a string: %s\n", num, str);
} else {
perror("Error reading from file");
}
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们首先打开一个名为 "example.txt" 的文件以读取模式("r")。然后,我们定义了一个整数变量 num 和一个字符数组 str,用于存储从文件中读取的数据。接着,我们使用 fscanf 函数读取一个整数和一个字符串,并将它们分别存储在 num 和 str 中。如果读取成功,我们打印出读取的数据;如果发生错误,我们打印错误消息并返回。最后,我们关闭文件以确保释放了与文件关联的资源。

fprintf

在C语言中,fprintf 是一个标准库函数,用于将格式化的输出写入到指定的文件流中。这个函数在 <stdio.h> 头文件中定义,并且其使用方式与 printf 类似,但它是将数据写入文件,而不是标准输出(通常是终端或控制台)。

函数原型

int fprintf(FILE *stream, const char *format, ...);

参数

  • stream:一个指向 FILE 对象的指针,该对象标识了要写入数据的文件流。
  • format:一个格式字符串,指定了输出数据的格式。
  • ...:根据格式字符串的要求,这里可以有多个额外的参数,用于提供要输出的数据。

返回值

  • 如果成功,fprintf 函数返回成功写入的字符数(不包括字符串末尾的空字符)。
  • 如果发生错误,返回负值。

注意事项

  • fprintf 函数使用格式字符串来确定如何格式化输出数据,并将其写入到指定的文件流中。
  • 格式字符串中的转换说明符(如 %d%f%s 等)用于指定要输出的数据类型。
  • 写入的数据可能包含换行符(\n),这会导致文件中的内容在新的一行开始。

示例

以下是一个简单的示例,展示了如何使用 fprintf 函数将格式化的数据写入到一个文件中:

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "w"); // 打开文件以写入("w" 模式)
if (file == NULL) {
perror("Error opening file");
return 1;
}
int num = 123;
float floatNum = 45.67f;
char str[] = "Hello, World!";
// 将数据写入文件
fprintf(file, "Integer: %d\n", num);
fprintf(file, "Float: %f\n", floatNum);
fprintf(file, "String: %s\n", str);
fclose(file); // 关闭文件
printf("Data written to example.txt successfully.\n");
return 0;
}

在这个示例中,我们首先打开一个名为 "example.txt" 的文件以写入模式("w")。然后,我们定义了几个变量 numfloatNum 和 str,用于存储要写入文件的数据。接着,我们使用 fprintf 函数将这些数据以指定的格式写入到文件中。最后,我们关闭文件以确保所有的数据都被正确写入,并打印一条消息表示数据已成功写入文件。如果文件打开失败,perror 函数将打印出相应的错误信息。

fread

在C语言中,fread 是一个标准库函数,用于从指定的文件流中读取数据块。这个函数在 <stdio.h> 头文件中定义,并允许你以二进制或文本模式读取文件中的数据。

函数原型

size_t fread(void *ptr, size_t size, size_t count, FILE *stream);

参数

  • ptr:一个指向要存储读取数据的内存块的指针。
  • size:要读取的每个数据项的大小(以字节为单位)。
  • count:要读取的数据项的数量。
  • stream:一个指向 FILE 对象的指针,该对象标识了要从中读取数据的文件流。

返回值

  • 如果成功,fread 函数返回实际读取的数据项数(即 count 参数和实际读取项数的较小值)。
  • 如果发生错误或在读取任何数据之前就已经遇到文件结束符(EOF),返回的值可能小于 count
  • 如果遇到文件结束符,返回的值将是已读取的项数(可能小于 count)。

注意事项

  • fread 函数按指定的数据项大小和数量从文件流中读取数据,并将这些数据存储在提供的内存块中。
  • 与 fscanf 不同,fread 不会根据格式字符串来解析数据,而是直接读取原始字节。
  • fread 通常用于二进制文件的读取,因为它不会处理文本文件的换行符转换(例如,在Windows系统中的 \r\n 到 Unix/Linux 中的 \n)。

示例

以下是一个简单的示例,展示了如何使用 fread 函数从一个文件中读取一定数量的字节:

#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file = fopen("example.bin", "rb"); // 打开二进制文件以读取("rb" 模式)
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 假设我们想要读取100个字节
size_t size_to_read = 100;
char buffer[size_to_read]; // 分配足够的内存来存储读取的数据
// 读取数据
size_t items_read = fread(buffer, 1, size_to_read, file);
// 检查是否读取了所有请求的数据
if (items_read != size_to_read) {
if (feof(file)) {
printf("End of file reached before reading %zu bytes.\n", size_to_read);
} else {
perror("Error reading file");
}
} else {
// 可以在这里处理读取的数据...
// 例如,打印前10个字节:
for (size_t i = 0; i < 10 && i < items_read; ++i) {
printf("%02X ", (unsigned char)buffer[i]);
}
printf("\n");
}
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们打开一个名为 "example.bin" 的二进制文件,并尝试读取100个字节的数据。我们分配了一个足够大的缓冲区来存储这些数据,并使用 fread 函数读取它们。然后,我们检查是否读取了所有请求的数据,并在需要时处理任何错误或文件结束的情况。最后,我们关闭文件并返回。

fwrite

在C语言中,fwrite 是一个标准库函数,用于将数据块写入到指定的文件流中。这个函数在 <stdio.h> 头文件中定义,通常用于二进制文件的写入,因为它不会处理文本文件的换行符转换或其他字符编码问题。

函数原型

size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);

参数

  • ptr:一个指向要写入文件的内存块的指针。
  • size:要写入的每个数据项的大小(以字节为单位)。
  • count:要写入的数据项的数量。
  • stream:一个指向 FILE 对象的指针,该对象标识了要写入数据的文件流。

返回值

  • 如果成功,fwrite 函数返回实际写入的数据项数(即 count 参数和实际写入项数的较小值)。
  • 如果发生错误,返回的值可能小于 count

注意事项

  • fwrite 函数按指定的数据项大小和数量将数据写入到文件流中。
  • 与 fprintf 不同,fwrite 不会根据格式字符串来格式化数据,而是直接写入原始字节。
  • fwrite 通常用于二进制文件的写入,因为它不会处理文本文件的换行符转换(例如,在Windows系统中的 \r\n 到 Unix/Linux 中的 \n)。

示例

以下是一个简单的示例,展示了如何使用 fwrite 函数将一个字符串写入到一个文件中:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *file = fopen("example.bin", "wb"); // 打开二进制文件以写入("wb" 模式)
if (file == NULL) {
perror("Error opening file");
return 1;
}
char *str = "Hello, World!";
size_t str_len = strlen(str) + 1; // 加上字符串末尾的空字符
// 写入数据
size_t items_written = fwrite(str, 1, str_len, file);
// 检查是否写入了所有请求的数据
if (items_written != str_len) {
perror("Error writing to file");
} else {
printf("String written to file successfully.\n");
}
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们打开一个名为 "example.bin" 的二进制文件以写入模式("wb")。然后,我们定义了一个字符串 str 和一个变量 str_len 来存储字符串的长度(包括末尾的空字符)。接着,我们使用 fwrite 函数将字符串写入到文件中,并检查是否成功写入了所有请求的数据。最后,我们关闭文件并返回。如果文件打开失败或写入过程中发生错误,perror 函数将打印出相应的错误信息。

sscnaf

在C语言中,sscanf 是一个标准库函数,用于从字符串中读取格式化的输入。这个函数类似于 scanf,但它是从给定的字符串中读取数据,而不是从标准输入流(通常是键盘)中读取。sscanf 函数在 <stdio.h> 头文件中定义。

函数原型

int sscanf(const char *str, const char *format, ...);

参数

  • str:一个指向要从中读取数据的字符串的指针。
  • format:一个格式字符串,指定了如何解释 str 中的内容。
  • ...:根据格式字符串的要求,这里可以有多个额外的参数,用于存储从 str 中读取的数据。

返回值

  • 如果成功,sscanf 函数返回成功读取并赋值的变量数。
  • 如果读取失败或到达字符串末尾之前发生匹配失败,返回值小于预期的变量数。
  • 如果在第一个转换之前发生错误,返回值为 EOF。

注意事项

  • sscanf 函数使用格式字符串来确定如何从 str 中读取数据,并将其存储在提供的变量中。
  • 格式字符串中的转换说明符(如 %d%f%s 等)用于指定要读取的数据类型。
  • 与 scanf 类似,sscanf 在读取字符串时会跳过空白字符(空格、制表符和换行符),除非格式字符串中包含空白字符的显式匹配(如 %n%c%[)。

示例

以下是一个简单的示例,展示了如何使用 sscanf 函数从字符串中读取整数和浮点数:

#include <stdio.h>
int main() {
char input[] = "42 3.14";
int num;
float floatNum;
// 从字符串中读取数据
int result = sscanf(input, "%d %f", &num, &floatNum);
// 检查是否成功读取了两个数据项
if (result == 2) {
printf("Integer: %d\n", num);
printf("Float: %f\n", floatNum);
} else {
printf("Failed to read both values from the string.\n");
}
return 0;
}

在这个示例中,我们定义了一个字符串 input,它包含了一个整数和一个浮点数。然后,我们使用 sscanf 函数从这个字符串中读取这两个值,并将它们存储在变量 num 和 floatNum 中。最后,我们检查 sscanf 的返回值,确保成功读取了两个数据项,并打印出这两个值。如果读取失败,则打印一条错误消息。

sprintf

在C语言中,sprintf 是一个标准库函数,用于将格式化的数据写入到字符串中。这个函数类似于 printf,但它是将数据写入到指定的字符串中,而不是输出到标准输出流(通常是控制台)。sprintf 函数在 <stdio.h> 头文件中定义。

函数原型

int sprintf(char *str, const char *format, ...);

参数

  • str:一个指向要写入数据的字符串的指针。这个字符串应该足够大,以容纳格式化后的数据以及一个额外的空字符(\0),用于表示字符串的结束。
  • format:一个格式字符串,指定了如何将数据转换为字符串,以及数据的顺序和类型。
  • ...:根据格式字符串的要求,这里可以有多个额外的参数,用于提供要写入字符串的数据。

返回值

  • 如果成功,sprintf 函数返回写入的字符数(不包括末尾的空字符)。
  • 如果发生错误,返回值是负数。

注意事项

  • 使用 sprintf 时需要特别小心,因为如果你提供的目标字符串 str 不够大,以容纳格式化后的数据以及空字符,那么就会发生缓冲区溢出(buffer overflow),这是一个严重的安全问题。
  • 为了避免缓冲区溢出,可以使用 snprintf 函数,它允许你指定目标字符串的最大大小。

示例

以下是一个简单的示例,展示了如何使用 sprintf 函数将整数和浮点数格式化为字符串:

#include <stdio.h>
int main() {
char buffer[50]; // 足够大的缓冲区来容纳格式化后的字符串和空字符
int num = 42;
float floatNum = 3.14;
// 将数据格式化为字符串并写入到 buffer 中
sprintf(buffer, "Integer: %d, Float: %.2f", num, floatNum);
// 打印 buffer 中的内容
printf("%s\n", buffer);
return 0;
}

在这个示例中,我们定义了一个足够大的字符数组 buffer 来存储格式化后的字符串。然后,我们使用 sprintf 函数将整数 num 和浮点数 floatNum 格式化为字符串,并将结果写入到 buffer 中。最后,我们使用 printf 函数打印出 buffer 中的内容。如果你运行这个程序,它会在控制台上输出 Integer: 42, Float: 3.14

fseek

在C语言中,fseek是一个用于移动文件内部指针位置的标准库函数。这个函数属于文件I/O(输入/输出)的一部分,它允许你在文件中跳转到指定的位置,以便从该位置开始读取或写入数据。fseek函数在<stdio.h>头文件中定义。

函数原型

int fseek(FILE *stream, long offset, int whence);

参数

  • stream:一个指向FILE对象的指针,表示要操作的文件流。
  • offset:从whence指定的位置开始计算的偏移量(以字节为单位)。
  • whence:这是起始点,用于确定offset如何应用于文件位置。它可以是以下三个常量之一:
    • SEEK_SET:文件的开始(0位置)。
    • SEEK_CUR:当前文件位置。
    • SEEK_END:文件的末尾。

返回值

如果成功,fseek返回0;如果发生错误,它返回非零值。

注意事项

  • fseek主要用于二进制文件,因为它基于字节进行操作。对于文本文件,由于可能存在换行符的转换(例如,在Windows系统中是\r\n,而在Unix/Linux系统中是\n),因此使用fseek可能不会得到预期的结果。
  • 在使用fseek之前,文件必须以二进制模式("rb""wb""ab"等)或文本模式("r""w""a"等,但在某些系统上可能不会按预期工作)打开。
  • 在使用fseek后,通常接下来的文件操作(如freadfwrite)将从新的文件位置开始。

示例

以下是一个简单的示例,展示了如何使用fseek函数在文件中跳转到特定位置并读取数据:

#include <stdio.h>
int main() {
FILE *file = fopen("example.bin", "rb"); // 以二进制读模式打开文件
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 假设文件中有足够的数据,我们想从第100个字节开始读取
if (fseek(file, 100, SEEK_SET) != 0) { // 跳转到文件的第100个字节
perror("Error seeking in file");
fclose(file);
return 1;
}
// 读取并打印接下来的10个字节(假设它们可以被安全地解释为字符)
char buffer[11]; // 额外的空间用于空字符
if (fread(buffer, 1, 10, file) != 10) { // 读取10个字节
perror("Error reading from file");
} else {
buffer[10] = '\0'; // 添加空字符以确保字符串正确终止
printf("Read from file: %s\n", buffer);
}
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们首先打开一个名为example.bin的二进制文件。然后,我们使用fseek函数将文件指针移动到文件的第100个字节。接着,我们使用fread函数从该位置开始读取10个字节,并将它们打印到控制台上。最后,我们关闭文件并退出程序。

ftell

在C语言中,ftell是一个用于获取文件内部指针当前位置的函数。它返回从文件开始到当前文件指针位置的偏移量(以字节为单位)。这个函数对于随机访问文件(如二进制文件)特别有用,因为它允许你了解当前读取或写入的位置。ftell函数在<stdio.h>头文件中定义。

函数原型

long ftell(FILE *stream);

参数

  • stream:一个指向FILE对象的指针,表示要操作的文件流。

返回值

如果成功,ftell返回一个长整数,表示从文件开始到当前文件指针位置的偏移量(以字节为单位)。如果发生错误或流不是有效的文件流,返回值可能是-1L(即LONG_MAX,这取决于系统和编译器的实现)。

注意事项

  • ftell主要用于二进制文件,因为它基于字节进行操作。对于文本文件,由于可能存在换行符的转换(例如,在Windows系统中是\r\n,而在Unix/Linux系统中是\n),因此使用ftell可能不会得到预期的字符位置。
  • 在使用ftell之前,文件必须已经以某种模式(如二进制模式"rb""wb""ab"或文本模式"r""w""a")打开。

示例

以下是一个简单的示例,展示了如何使用ftell函数来获取当前文件指针位置,并将它打印出来:

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r"); // 以文本读模式打开文件
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 读取一些字符(这里假设文件中有足够的数据)
char buffer[10];
if (fread(buffer, 1, sizeof(buffer) - 1, file) == 0) {
perror("Error reading from file");
fclose(file);
return 1;
}
buffer[sizeof(buffer) - 1] = '\0'; // 确保字符串正确终止
// 获取当前文件指针位置并打印
long position = ftell(file);
if (position == -1L) {
perror("Error getting file position");
fclose(file);
return 1;
}
printf("Current file position: %ld bytes\n", position);
// 继续处理文件...
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们首先打开一个名为example.txt的文本文件。然后,我们读取一些字符到缓冲区中,并使用ftell获取并打印出当前的文件指针位置。注意,在实际应用中,你可能会在文件操作的某个特定点(如读取或写入数据后)使用ftell来跟踪文件指针的位置。

rewind 

在C语言中,rewind函数是一个用于重置文件内部指针到文件开头的标准库函数。当你想要重新从头开始读取文件时,这个函数是非常有用的。rewind函数在<stdio.h>头文件中定义。

函数原型

void rewind(FILE *stream);

参数

  • stream:一个指向FILE对象的指针,表示要操作的文件流。

返回值

rewind函数没有返回值。如果成功,文件内部指针会被重置到文件的开头;如果失败(例如,stream不是一个有效的文件指针),则可能会产生未定义的行为。

注意事项

  • 在调用rewind之后,接下来的文件操作(如freadfscanf)将从文件的开头开始。
  • rewind通常用于文本文件和二进制文件。

示例

以下是一个简单的示例,展示了如何使用rewind函数来重置文件指针并重新读取文件的内容:

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r"); // 以文本读模式打开文件
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 第一次读取文件内容(假设文件中有足够的数据)
char buffer[100];
if (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("First line of file: %s", buffer);
}
// 使用rewind重置文件指针到文件开头
rewind(file);
// 第二次读取文件内容(应该从文件的开头开始)
if (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("First line of file (after rewind): %s", buffer);
}
fclose(file); // 关闭文件
return 0;
}

在这个示例中,我们首先打开一个名为example.txt的文本文件,并使用fgets函数读取文件的第一行。然后,我们使用rewind函数将文件指针重置到文件的开头,并再次使用fgets函数读取文件的第一行(此时应该再次得到相同的内容)。最后,我们关闭文件并退出程序。

ferror

在C语言中,ferror 是一个函数,用于检查与指定的文件流或流(stream)相关联的错误标志是否已被设置。如果在最近的I/O操作中发生了错误(例如,读取或写入文件时磁盘空间不足、文件不存在、权限问题等),ferror 将返回非零值(通常是1),表示发生了错误。

函数的原型如下:

int ferror(FILE *stream);

其中,stream 是指向 FILE 对象的指针,该对象标识了要检查的文件流。

以下是一个简单的示例,展示如何使用 ferror 函数:

#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
FILE *file = fopen("nonexistentfile.txt", "r");
if (file == NULL) {
// fopen 失败,打印错误并退出
perror("Failed to open file");
return 1;
}
// 尝试从文件中读取数据(但文件不存在,所以这里会失败)
char buffer[1024];
if (fgets(buffer, sizeof(buffer), file) == NULL) {
// fgets 失败,检查是否是 I/O 错误
if (ferror(file)) {
printf("I/O error occurred while reading the file\n");
// 清除错误标志,以便后续操作
clearerr(file);
} else {
// fgets 返回 NULL 但 ferror 返回 0,可能是 EOF 或其他非 I/O 错误
printf("End of file or other non-I/O error occurred\n");
}
}
// 关闭文件
fclose(file);
return 0;
}

注意,在调用 ferror 之后,如果你打算继续使用该流进行I/O操作,并且希望清除错误标志,可以使用 clearerr 函数。

此外,虽然 ferror 函数可以告诉你是否发生了I/O错误,但它不会告诉你具体是什么错误。要了解更详细的错误信息,你可能需要检查全局变量 errno(在 <errno.h> 中定义),或者使用其他特定于平台的函数或方法。

perror

在C语言中,perror 是一个函数,用于在标准错误流(通常是stderr)上打印一个描述最近系统调用的错误信息的字符串。这个函数通常与全局变量 errno 一起使用,因为 errno 通常被设置为上一个系统调用的错误代码。

perror 的函数原型如下:

void perror(const char *str);

其中,str 是一个指向字符串的指针,该字符串将被打印在错误信息之前。如果 str 是 NULL,则不打印任何字符串,只打印错误信息。

perror 函数会首先打印传入的字符串(如果非 NULL),然后是一个冒号、一个空格,以及对应于 errno 当前值的错误描述字符串。这个描述字符串是由系统提供的,描述了与 errno 值对应的错误。

以下是一个使用 perror 的简单示例:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
FILE *file = fopen("nonexistentfile.txt", "r");
if (file == NULL) {
// fopen 失败,使用 perror 打印错误信息
perror("Failed to open file");
// 退出程序
exit(EXIT_FAILURE);
}
// ... 其他文件操作 ...
// 关闭文件
fclose(file);
return 0;
}

在这个例子中,如果 fopen 调用失败(例如,因为文件不存在或没有读取权限),file 将是 NULL,然后 perror 将被调用以打印一个描述错误的消息。这个消息将类似于 "Failed to open file: No such file or directory"(但实际的消息可能会因操作系统和区域设置的不同而略有不同)。

请注意,perror 只会打印与 errno 相关的错误。如果错误不是由系统调用引起的(例如,是由 malloc 引起的内存分配失败),则 errno 可能不会被设置,因此 perror 可能不会打印有用的信息。在这些情况下,您可能需要使用其他方法(如 strerror 函数)来处理错误。

feof

在C语言中,feof是一个函数,用于检查文件结束(End of File, EOF)标志是否已经被设置。当尝试从文件读取数据,但已经没有更多数据可读(即已经到达文件的末尾)时,文件的EOF标志会被设置。此时,feof函数会返回非零值(通常是1),表示已经到达文件的末尾。

feof函数的原型如下:

int feof(FILE *stream);

其中,stream是指向FILE对象的指针,该对象标识了要检查的文件流。

下面是一个使用feof函数的简单示例:

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
perror("Failed to open file");
return 1;
}
char ch;
// 循环读取文件中的字符,直到到达文件末尾
while (!feof(file)) {
ch = fgetc(file); // 从文件中读取一个字符
if (ferror(file)) { // 检查是否发生I/O错误
perror("Error reading file");
break;
}
if (ch != EOF) { // 过滤掉EOF(在文本模式下,fgetc在EOF时返回EOF,而不是字符)
putchar(ch); // 打印读取到的字符
}
}
if (!feof(file)) {
// 如果不是由于到达文件末尾而退出循环(即发生了I/O错误),则打印错误消息
perror("I/O error occurred");
}
fclose(file); // 关闭文件
return 0;
}

请注意,在上面的示例中,我们使用了fgetc函数从文件中读取字符,并检查了ferror以确保没有发生I/O错误。当fgetc在文件末尾时,它会返回特殊的EOF值(通常是-1,但在C语言中,EOF是在<stdio.h>中定义的一个宏,其值可能因系统和编译器而异)。然而,我们仍然需要检查feof,因为fgetc在发生I/O错误时也可能返回EOF。

另外,值得注意的是,在循环中使用feof作为条件可能不是最佳做法,因为当文件为空或在读取第一个字符之前就发生错误时,feof可能不会被设置。更常见的做法是在尝试读取之后检查EOF或I/O错误。上面的示例展示了如何安全地处理这些情况。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值