文件指针在C语言函数中如何使用?

99ANYc3cd6
预计阅读时长 21 分钟
位置: 首页 C语言 正文

第一部分:函数

函数是 C 语言程序的基本构建块,它是一段可以重复使用的代码,用于执行特定的任务,使用函数可以带来以下好处:

c语言 函数 文件指针
(图片来源网络,侵删)
  • 代码重用:避免编写重复的代码。
  • 模块化:将复杂的问题分解为小的、易于管理的部分。
  • 可读性:使代码结构更清晰,易于理解和维护。
  • 易于调试:可以单独测试和调试每个函数。

函数的基本结构

一个完整的函数定义包含以下几个部分:

返回类型 函数名(参数列表) {
    // 函数体
    // 执行的代码
    return 返回值; // 如果返回类型不是 void
}
  • 返回类型:函数执行完毕后返回给调用者的数据的类型,如果函数不返回任何值,则使用 void
  • 函数名:给函数起的名称,用于调用。
  • 参数列表:传递给函数的变量的列表,多个参数用逗号隔开,如果函数不接受任何参数,可以使用 void或者留空(在 C99 标准之后,留空 表示无参数)。
  • 函数体:包含在一对花括号 中的代码,是函数实际执行的部分。
  • return 语句:用于从函数返回一个值,并终止函数的执行,如果返回类型是 voidreturn 语句可以省略,或者只写 return;

函数的示例

示例 1:无参数,无返回值

#include <stdio.h>
// 函数声明
void printWelcomeMessage();
int main() {
    printWelcomeMessage(); // 函数调用
    return 0;
}
// 函数定义
void printWelcomeMessage() {
    printf("欢迎来到 C 语言世界!\n");
}

示例 2:有参数,有返回值

#include <stdio.h>
// 函数声明
int add(int a, int b);
int main() {
    int num1 = 5;
    int num2 = 10;
    int sum;
    sum = add(num1, num2); // 函数调用,并接收返回值
    printf("和为: %d\n", sum);
    return 0;
}
// 函数定义
int add(int a, int b) {
    return a + b; // 返回 a 和 b 的和
}

第二部分:文件指针

在 C 语言中,对文件的所有操作都是通过文件指针来完成的,文件指针是一个指向 FILE 结构体的指针,该结构体包含了文件操作所需的所有信息(如文件名、状态、当前位置等)。

c语言 函数 文件指针
(图片来源网络,侵删)

FILEfopen

  • FILE:这是一个在 <stdio.h> 中定义的结构体类型,你不需要关心它的具体内部结构,只需要知道它代表了文件流。
  • fopen():这是一个标准库函数,用于打开文件,并返回一个指向该文件的 FILE 指针。
FILE *fopen(const char *filename, const char *mode);
  • filename:要打开的文件名(可以包含路径)。
  • mode:文件打开模式,决定了你如何使用这个文件。
模式 含义 如果文件不存在 如果文件存在
"r" 只读 报错 打开成功
"w" 只写 创建新文件 清空文件内容
"a" 追加 创建新文件 在文件末尾写入
"r+" 读写 报错 打开成功,指针在开头
"w+" 读写 创建新文件 清空文件内容
"a+" 读写 创建新文件 打开成功,指针在末尾

重要fopen 可能会因为文件无法打开(如路径错误、权限不足等)而失败,此时它会返回 NULL,在每次使用 fopen 后,必须检查返回值是否为 NULL

文件操作常用函数

一旦你通过 fopen 获得了文件指针,就可以使用一系列函数来操作文件。

函数 功能
fprintf(fp, "...", ...) 格式化写入数据到文件
fscanf(fp, "...", ...) 从文件格式化读取数据
fputc(c, fp) 写入一个字符到文件
fgetc(fp) 从文件读取一个字符
fputs(s, fp) 写入一个字符串到文件
fgets(s, n, fp) 从文件读取一行字符串
fseek(fp, offset, origin) 移动文件指针到指定位置
ftell(fp) 获取当前文件指针的位置
rewind(fp) 将文件指针重置到文件开头
fwrite(buffer, size, count, fp) 以二进制形式写入一块数据
fread(buffer, size, count, fp) 以二进制形式读取一块数据
fclose(fp) 关闭文件

文件操作完整示例

下面是一个完整的示例,演示了如何创建、写入、读取和关闭文件。

#include <stdio.h>
#include <string.h> // 使用 strcpy 函数
int main() {
    // 1. 定义文件指针
    FILE *fp;
    char filename[] = "my_data.txt";
    char content[100] = "这是要写入文件的第一行内容,\n";
    char read_content[100];
    // 2. 以写模式 ("w") 打开文件
    // 注意:一定要检查 fopen 是否成功!
    fp = fopen(filename, "w");
    if (fp == NULL) {
        printf("无法打开文件 %s\n", filename);
        return 1; // 返回非零值表示程序出错
    }
    // 3. 写入数据到文件
    fprintf(fp, "%s", content);
    fputs("这是用 fputs 写入的第二行,\n", fp);
    printf("数据已成功写入 %s\n", filename);
    // 4. 关闭文件
    fclose(fp);
    // --- 接下来是读取文件部分 ---
    // 5. 以读模式 ("r") 打开文件
    fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("无法打开文件 %s 进行读取\n", filename);
        return 1;
    }
    // 6. 从文件读取数据
    printf("\n--- 开始读取文件内容 ---\n");
    // 使用 fgets 读取一行
    if (fgets(read_content, sizeof(read_content), fp) != NULL) {
        printf("读取到第一行: %s", read_content);
    }
    // 使用 fscanf 读取
    // 注意:fscanf 遇到空格会停止,所以不适合读取包含空格的行
    // 这里我们假设下一行是简单的数字和字符串
    fprintf(fp, "用户ID: 1001\n"); // 先写入一些结构化数据以便演示
    rewind(fp); // 重置指针到文件开头
    int id;
    char name[50];
    if (fscanf(fp, "用户ID: %d\n", &id) == 1) {
        printf("读取到用户ID: %d\n", id);
    }
    // 重置指针到文件开头,以便读取完整内容
    rewind(fp);
    printf("\n--- 文件完整内容 ---\n");
    while (fgets(read_content, sizeof(read_content), fp) != NULL) {
        printf("%s", read_content);
    }
    // 7. 关闭文件
    fclose(fp);
    return 0;
}

错误处理:perrorerrno

当文件操作失败时,fopen 等函数会返回 NULL,为了了解具体的错误原因,可以使用 perror 函数。

c语言 函数 文件指针
(图片来源网络,侵删)
fp = fopen("non_existent_file.txt", "r");
if (fp == NULL) {
    // perror 会打印你提供的字符串,然后加上一个冒号和系统错误信息
    perror("打开文件失败"); 
    // 可能的输出: "打开文件失败: No such file or directory"
    return 1;
}

第三部分:函数与文件指针的结合

在实际编程中,我们经常将文件操作封装成独立的函数,以提高代码的模块化和复用性。

示例:一个简单的日志记录函数

#include <stdio.h>
#include <time.h>
#include <string.h>
// 函数声明
void log_message(const char *filename, const char *message);
int main() {
    log_message("app.log", "程序启动成功。");
    log_message("app.log", "用户登录。");
    log_message("app.log", "程序准备退出。");
    return 0;
}
// 函数定义:向日志文件追加一条记录
void log_message(const char *filename, const char *message) {
    FILE *fp = fopen(filename, "a"); // 使用 "a" 模式进行追加
    if (fp == NULL) {
        perror("无法打开日志文件");
        return; // 如果打不开文件,函数直接返回
    }
    // 获取当前时间
    time_t now;
    time(&now);
    char *time_str = ctime(&now);
    time_str[strlen(time_str) - 1] = '\0'; // 去掉 ctime 添加的换行符
    // 写入日志内容
    fprintf(fp, "[%s] %s\n", time_str, message);
    // 关闭文件
    fclose(fp);
}

这个例子中,log_message 函数专门负责处理日志写入。main 函数只需要调用它,而不需要关心文件是如何打开和关闭的,这使得代码非常清晰。

概念 关键点
函数 是可重用的代码块,有返回类型、函数名、参数列表和函数体,用于模块化编程。
文件指针 是一个指向 FILE 结构体的指针,是所有文件操作的入口。
fopen 用于打开文件,必须检查其返回值是否为 NULL
文件操作 使用 fprintf, fscanf, fgets, fputs 等函数进行读写。
fclose 非常重要!操作完成后必须关闭文件,释放资源。
结合使用 将文件操作封装在函数中,是编写健壮、可维护 C 程序的良好实践。
-- 展开阅读全文 --
头像
C语言入门经典为何难理解?
« 上一篇 今天
c语言 eof等于多少
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

目录[+]