【C语言】 “函数指针”和“指针函数” 用法和详解(太细了!!!)菜鸟级教程

本文详细比较了标准I/O和系统I/O在接口、缓冲和错误处理方面的特点,提供了标准I/O函数如fopen和fprintf的使用示例,并展示了如何使用系统调用如open和write进行底层操作,以及错误处理的方法。
摘要由CSDN通过智能技术生成


一、标准 I/O 和系统 I/O的区别

1.高层接口 vs 低层接口

1、标准 I/O
(1)标准 I/O 函数是高层接口,提供了一组方便的函数(如 fopen、fprintf、fread 等)来进行文件的读写操作。
(2)它们抽象了底层系统调用,更容易使用,且具有跨平台性。
2、系统 I/O
(1)系统 I/O 是低层接口,它使用系统调用(如 open、read、write 等)来直接操作文件。
(2)调用提供更底层的控制,但通常需要更多的代码和对操作系统的了解。

2.缓冲

1、标准 I/O:
(1)标准 I/O 函数自动进行缓冲,数据通常首先被读入或写出到一个内部缓冲区,然后根据需要进行实际的 I/O 操作。
(2)可以提高性能,尤其是在频繁的小数据量读写时。
2、系统 I/O:
(1)系统 I/O 通常不提供自动缓冲,你需要自己手动管理缓冲区。
(2)这使得对文件的读写更加直接,但可能需要更多的编程工作。

3.错误处理

1、标准 I/O:
(1)标准 I/O 函数使用 NULL 指针返回错误,可以使用 feof 和 ferror 函数来检查文件尾和错误状态。
(2)错误消息可以通过 perror 函数输出。
2、系统 I/O:
(1)系统 I/O 函数通常返回 -1 来表示错误,可以通过查看 errno 全局变量来获取特定的错误代码,然后使用 perror 或 strerror 函数将错误消息打印出来。

二、"标准I/O"的使用

(1)使用 fopen 函数打开一个文件以供写入,如果文件不存在则创建。如果打开失败,它会使用 perror 函数打印错误消息,并返回错误码 1。
(2)使用 fprintf 函数将文本写入文件。
(3)使用 fclose 函数关闭文件。
(4)使用 fopen 函数再次打开文件以供读取。如果打开失败,它会再次使用 perror 函数打印错误消息,并返回错误码 1。
(5)使用 fgets 函数逐行读取文件内容,直到文件末尾。每一行都会被存储在 buffer 缓冲区中。
(6)使用 printf 函数打印从文件中读取的每一行内容。
(7)使用 fclose 函数关闭文件。
(8)最后,程序返回 0 表示成功结束。

代码如下(示例):

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 打开一个文件以供写入,如果文件不存在则创建 ("w" 模式)
    FILE *file = fopen("stdio_example.txt", "w");
    if (file == NULL) {
        perror("无法打开文件"); // 打印错误消息并返回错误码
        return 1;
    }

    // 写入文件
    fprintf(file, "这是标准I/O写入的文本\n");
    fclose(file); // 关闭文件

    // 重新打开文件以供读取 ("r" 模式)
    file = fopen("stdio_example.txt", "r");
    if (file == NULL) {
        perror("无法打开文件"); // 打印错误消息并返回错误码
        return 1;
    }

    char buffer[100];
    // 逐行读取文件内容,直到文件末尾
    while (fgets(buffer, sizeof(buffer), file) != NULL) {
        printf("标准I/O读取: %s", buffer); // 打印每行内容
    }
    fclose(file); // 关闭文件

    return 0; // 成功结束程序
}
 输出结果:标准I/O读取: 这是标准I/O写入的文本

三、"系统I/O"的使用

(1)使用 open 系统调用打开一个文件以供写入,如果文件不存在则创建,权限为 0644。如果打开失败,它会使用 strerror 函数打印错误消息和错误号,然后返回错误码 1 表示程序异常结束。
(2)使用 write 系统调用将文本写入文件。如果写入失败,它会使用 strerror 函数打印错误消息和错误号,关闭文件,然后返回错误码 1。
(3)使用 close 系统调用关闭文件。
(4)重新使用 open 系统调用打开文件以供读取(“O_RDONLY” 模式)。如果打开失败,它会使用 strerror 函数打印错误消息和错误号,然后返回错误码 1。
(5)使用 read 系统调用逐块读取文件内容,直到文件末尾。每块内容都被存储在 buffer 缓冲区中。
(6)使用 write 系统调用将读取的内容写入标准输出。如果写入失败,它会使用 strerror 函数打印错误消息和错误号,关闭文件,然后返回错误码 1。
(7)使用 close 系统调用关闭文件。
(8)最后,如果一切正常,程序返回 0 表示成功结束。

代码如下(示例):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main() {
    // 打开一个文件以供写入,如果文件不存在则创建,权限为 0644
    int fd = open("syscalls_example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        fprintf(stderr, "无法打开文件: %s\n", strerror(errno)); // 打印错误消息和错误号
        return 1; // 返回错误码 1 表示程序异常结束
    }

    // 写入文件
    char *text = "这是系统I/O写入的文本\n";
    ssize_t bytesWritten = write(fd, text, strlen(text)); // 写入文件内容
    if (bytesWritten == -1) {
        fprintf(stderr, "写入文件时发生错误: %s\n", strerror(errno)); // 打印错误消息和错误号
        close(fd); // 关闭文件
        return 1; // 返回错误码 1 表示程序异常结束
    }
    close(fd); // 关闭文件

    // 重新打开文件以供读取 ("O_RDONLY" 模式)
    fd = open("syscalls_example.txt", O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "无法打开文件: %s\n", strerror(errno)); // 打印错误消息和错误号
        return 1; // 返回错误码 1 表示程序异常结束
    }

    char buffer[100];
    ssize_t bytesRead;
    // 逐块读取文件内容,直到文件末尾
    while ((bytesRead = read(fd, buffer, sizeof(buffer))) > 0) {
        ssize_t bytesWritten = write(STDOUT_FILENO, buffer, bytesRead); // 将读取的内容写入标准输出
        if (bytesWritten == -1) {
            fprintf(stderr, "写入标准输出时发生错误: %s\n", strerror(errno)); // 打印错误消息和错误号
            close(fd); // 关闭文件
            return 1; // 返回错误码 1 表示程序异常结束
        }
    }
    close(fd); // 关闭文件

    return 0; // 成功结束程序
}
 输出结果:这是系统I/O写入的文本

粉丝福利、需求解答

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒创科技工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值