C语言 标准I/O函数全面指南

news2025/6/7 3:21:51

C标准I/O函数全面指南

本指南详细介绍了C语言中用于文件操作的标准输入/输出函数,包括单字符I/O、字符串I/O、格式化I/O、块I/O以及文件光标操作。每个部分包含函数定义、使用说明和实用示例,适合学习、复习以及博客发布。内容采用清晰的Markdown格式,代码规范,包含详细注释和最佳实践(如错误处理),以提升可读性和实用性。


1. 单字符读写:fputcfgetc

函数定义

  • fgetc

    #include <stdio.h>
    int fgetc(FILE *stream);
    
    • 功能:从指定文件中读取一个字符,并以无符号整数形式返回。
    • 参数stream - 文件指针。
    • 返回值
      • 成功:返回读取的字符(无符号整数形式)。
      • 失败:返回EOF并设置错误码。
  • fputc

    #include <stdio.h>
    int fputc(int c, FILE *stream);
    
    • 功能:将指定字符c写入到文件指针stream指向的文件中。
    • 参数
      • c:要写入的字符(以无符号整数形式传递)。
      • stream:文件指针。
    • 返回值
      • 成功:返回写入的字符(无符号整数形式)。
      • 失败:返回EOF并设置错误码。

示例代码

以下示例展示如何使用fputc写入字符到文件,并用fgetc读取文件内容。

#include <stdio.h>

int main() {
    // 定义文件指针
    FILE *fp = NULL;
    
    // 以只写模式打开文件
    if ((fp = fopen("file.txt", "w")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 写入字符串 "Hello",每次写入一个字符
    fputc('H', fp);
    fputc('e', fp);
    fputc('l', fp);
    fputc('l', fp);
    fputc('o', fp);
    
    fclose(fp); // 关闭文件
    
    // 以只读模式重新打开文件
    if ((fp = fopen("file.txt", "r")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 逐字符读取并打印
    char ch;
    while ((ch = fgetc(fp)) != EOF) {
        printf("%c ", ch);
    }
    
    fclose(fp); // 关闭文件
    return 0;
}

说明

  • 写入fputc每次写入一个字符,文件光标自动向后移动。
  • 读取fgetc每次读取一个字符,遇到文件末尾返回EOF
  • 注意:写入后光标位于文件末尾,直接读取会失败,因此需重新打开文件或使用rewind重置光标。

2. 字符串读写:fgetsfputs

函数定义

  • fputs

    #include <stdio.h>
    int fputs(const char *s, FILE *stream);
    
    • 功能:将字符串s写入到文件指针stream指向的文件中(不包含字符串结束符\0)。
    • 参数
      • s:要写入的字符串。
      • stream:文件指针。
    • 返回值
      • 成功:返回写入的字符数(非负数)。
      • 失败:返回EOF
  • fgets

    #include <stdio.h>
    char *fgets(char *s, int size, FILE *stream);
    
    • 功能:从文件指针stream指向的文件中读取最多size-1个字符到数组s,遇到换行符或文件末尾停止,并在末尾自动添加\0
    • 参数
      • s:存储读取数据的字符数组。
      • size:最多读取的字符数(包含末尾\0)。
      • stream:文件指针。
    • 返回值
      • 成功:返回s(字符数组起始地址)。
      • 失败或文件末尾:返回NULL

示例代码

以下示例展示如何从终端输入字符串并写入文件,再从文件中读取并显示。

#include <stdio.h>
#include <string.h>

int main() {
    // 定义文件指针
    FILE *fp = NULL;
    
    // 以只写模式打开文件
    if ((fp = fopen("file.txt", "w")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 从终端输入字符串并写入文件
    char wbuf[128];
    while (1) {
        printf("请输入字符串(输入quit退出):");
        fgets(wbuf, sizeof(wbuf), stdin); // 从标准输入读取
        wbuf[strcspn(wbuf, "\n")] = '\0'; // 移除换行符
        
        if (strcmp(wbuf, "quit") == 0) {
            break;
        }
        
        fputs(wbuf, fp); // 写入字符串
        fputc('\n', fp); // 添加换行符
    }
    
    fclose(fp);
    
    // 以只读模式打开文件
    if ((fp = fopen("file.txt", "r")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 逐行读取并打印
    char rbuf[128];
    while (fgets(rbuf, sizeof(rbuf), fp) != NULL) {
        printf("读取到:%s", rbuf);
    }
    
    fclose(fp);
    return 0;
}

说明

  • 写入fputs写入字符串,不包括\0,需手动添加换行符以分隔行。
  • 读取fgets读取一行(包含换行符),自动添加\0,适合逐行处理文本文件。
  • 注意fgets会保留输入的换行符,需用strcspn或类似方法移除。

3. 格式化读写:fprintffscanf

函数定义

  • fprintf

    #include <stdio.h>
    int fprintf(FILE *stream, const char *format, ...);
    
    • 功能:按指定格式将数据写入文件。
    • 参数
      • stream:文件指针(可为stdoutstderr)。
      • format:格式化字符串,包含格式控制符(如%d%s%f%lf)。
      • ...:可变参数,数量由格式控制符决定。
    • 返回值
      • 成功:返回写入的字符数。
      • 失败:返回负数。
  • fscanf

    #include <stdio.h>
    int fscanf(FILE *stream, const char *format, ...);
    
    • 功能:按指定格式从文件中读取数据到变量中。
    • 参数
      • stream:文件指针(可为stdin)。
      • format:格式化字符串,包含格式控制符。
      • ...:变量地址列表,数量由格式控制符决定。
    • 返回值
      • 成功:返回成功读取的项数。
      • 失败或文件末尾:返回EOF并设置错误码。

示例代码

以下示例展示格式化读写到标准输出/输入和外部文件。

#include <stdio.h>

int main() {
    // 向标准输出写入格式化数据
    fprintf(stdout, "整数: %d, 小数: %.2f, 字符串: %s\n", 520, 3.14, "I Love C");
    
    // 从标准输入读取整数
    int num;
    printf("请输入一个整数:");
    if (fscanf(stdin, "%d", &num) == 1) {
        printf("读取到:%d\n", num);
    } else {
        printf("读取失败\n");
    }
    
    // 写入格式化数据到文件
    FILE *fp = NULL;
    if ((fp = fopen("usr.txt", "w")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    fprintf(fp, "%s %d", "admin", 123456); // 写入用户名和密码
    fclose(fp);
    
    // 从文件中读取格式化数据
    if ((fp = fopen("usr.txt", "r")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    char usrName[20];
    int pwd;
    if (fscanf(fp, "%s %d", usrName, &pwd) == 2) {
        printf("用户名: %s, 密码: %d\n", usrName, pwd);
    } else {
        printf("读取失败\n");
    }
    
    fclose(fp);
    return 0;
}

说明

  • 格式化fprintffscanf支持多种数据类型(如整数、浮点数、字符串),灵活性高。
  • 标准I/O:使用stdoutstdin可直接操作终端输入输出。
  • 注意fscanf读取时需确保变量地址正确,格式匹配,否则可能导致错误。

4. 格式串转字符串:sprintfsnprintf

函数定义

  • sprintf

    #include <stdio.h>
    int sprintf(char *str, const char *format, ...);
    
    • 功能:将格式化数据转换为字符串,存储到字符数组str中。
    • 参数
      • str:目标字符数组。
      • format:格式化字符串。
      • ...:可变参数。
    • 返回值
      • 成功:返回转换的字符数(不含\0)。
      • 失败:返回EOF
  • snprintf

    #include <stdio.h>
    int snprintf(char *str, size_t size, const char *format, ...);
    
    • 功能:将格式化数据转换为字符串,最多存储size-1个字符到str,并添加\0
    • 参数
      • str:目标字符数组。
      • size:最大存储字符数(含\0)。
      • format:格式化字符串。
      • ...:可变参数。
    • 返回值
      • 成功:返回应写入的字符数(不含\0)。
      • 如果超出size:返回应写入的字符数(但只写入size-1个字符)。
      • 失败:返回EOF

示例代码

以下示例展示如何将多种数据类型组合成字符串。

#include <stdio.h>

int main() {
    char buf[20];
    
    // 使用 sprintf(不安全,可能溢出)
    sprintf(buf, "%d %s %.1f", 1001, "zhangsan", 99.5);
    printf("sprintf结果: %s\n", buf);
    
    // 使用 snprintf(安全,限制长度)
    snprintf(buf, sizeof(buf), "%d %s %.1f", 1001, "zhangsan", 99.5);
    printf("snprintf结果: %s\n", buf);
    
    return 0;
}

说明

  • 安全性sprintf可能导致缓冲区溢出,推荐使用snprintf以限制写入长度。
  • 用途:常用于将多种数据类型组合成字符串,便于后续处理或输出。
  • 注意:确保buf大小足够容纳格式化结果,snprintf更适合现代编程。

5. 模块化读写:freadfwrite

函数定义

  • fread

    #include <stdio.h>
    size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    
    • 功能:从文件读取nmemb项数据,每项大小为size字节,存储到ptr指向的内存。
    • 参数
      • ptr:存储数据的内存地址(支持任意类型)。
      • size:每项数据的大小(字节)。
      • nmemb:读取的项数。
      • stream:文件指针。
    • 返回值
      • 成功:返回实际读取的项数。
      • 失败或文件末尾:返回小于nmemb的值或0。
  • fwrite

    #include <stdio.h>
    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
    
    • 功能:将ptr指向的nmemb项数据(每项size字节)写入文件。
    • 参数
      • ptr:要写入的数据地址。
      • size:每项数据的大小(字节)。
      • nmemb:写入的项数。
      • stream:文件指针。
    • 返回值
      • 成功:返回实际写入的项数。
      • 失败:返回小于nmemb的值或0。

示例代码

字符串读写
#include <stdio.h>
#include <string.h>

int main() {
    FILE *fp = NULL;
    
    // 以只写模式打开文件
    if ((fp = fopen("test.txt", "w")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 循环输入字符串并写入
    char wbuf[128];
    while (1) {
        printf("请输入字符串(输入quit退出):");
        fgets(wbuf, sizeof(wbuf), stdin);
        wbuf[strcspn(wbuf, "\n")] = '\0';
        
        if (strcmp(wbuf, "quit") == 0) {
            break;
        }
        
        fwrite(wbuf, strlen(wbuf), 1, fp); // 写入字符串
        fwrite("\n", 1, 1, fp); // 添加换行
        fflush(fp); // 刷新缓冲区
    }
    
    fclose(fp);
    
    // 以只读模式打开文件
    if ((fp = fopen("test.txt", "r")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 读取并输出
    char rbuf[10];
    size_t res;
    while ((res = fread(rbuf, 1, sizeof(rbuf) - 1, fp)) > 0) {
        rbuf[res] = '\0'; // 添加结束符
        fwrite(rbuf, 1, res, stdout); // 输出到终端
    }
    
    fclose(fp);
    return 0;
}
整数读写
#include <stdio.h>

int main() {
    FILE *fp = NULL;
    
    // 以只写模式打开文件
    if ((fp = fopen("test.txt", "w")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 写入整数
    int num = 16;
    fwrite(&num, sizeof(int), 1, fp);
    
    fclose(fp);
    
    // 以只读模式打开文件
    if ((fp = fopen("test.txt", "r")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 读取整数
    int key;
    if (fread(&key, sizeof(int), 1, fp) == 1) {
        printf("读取到: %d\n", key);
    } else {
        printf("读取失败\n");
    }
    
    fclose(fp);
    return 0;
}
结构体读写
#include <stdio.h>
#include <string.h>

typedef struct {
    char name[20];
    int age;
    double score;
} Stu;

int main() {
    FILE *fp = NULL;
    
    // 以只写模式打开文件
    if ((fp = fopen("test.txt", "w")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 定义并写入学生数据
    Stu students[] = {
        {"张三", 18, 98.0},
        {"李四", 20, 88.0},
        {"王五", 16, 95.0}
    };
    fwrite(students, sizeof(Stu), 3, fp);
    
    fclose(fp);
    
    // 以只读模式打开文件
    if ((fp = fopen("test.txt", "r")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 读取并显示一个学生信息
    Stu temp;
    if (fread(&temp, sizeof(Stu), 1, fp) == 1) {
        printf("姓名: %s, 年龄: %d, 成绩: %.2f\n", temp.name, temp.age, temp.score);
    }
    
    fclose(fp);
    return 0;
}

说明

  • 灵活性freadfwrite支持任意数据类型(如字符串、整数、结构体),适合二进制文件操作。
  • 注意:二进制读写需确保数据结构对齐一致,跨平台时需考虑字节序。

6. 文件光标操作:fseek, ftell, rewind

函数定义

  • fseek

    #include <stdio.h>
    int fseek(FILE *stream, long offset, int whence);
    
    • 功能:移动文件光标到指定位置。
    • 参数
      • stream:文件指针。
      • offset:偏移量(正:向后,负:向前,0:不动)。
      • whence:起始位置(SEEK_SET:文件开头,SEEK_CUR:当前位置,SEEK_END:文件末尾)。
    • 返回值
      • 成功:返回0。
      • 失败:返回-1并设置错误码。
  • ftell

    #include <stdio.h>
    long ftell(FILE *stream);
    
    • 功能:获取文件光标的当前偏移量(相对于文件开头)。
    • 参数stream - 文件指针。
    • 返回值
      • 成功:返回当前偏移量(字节)。
      • 失败:返回-1并设置错误码。
  • rewind

    #include <stdio.h>
    void rewind(FILE *stream);
    
    • 功能:将文件光标重置到文件开头(等效于fseek(stream, 0, SEEK_SET))。
    • 参数stream - 文件指针。
    • 返回值:无。

示例代码

以下示例展示如何操作文件光标并读取特定位置的数据。

#include <stdio.h>
#include <string.h>

typedef struct {
    char name[20];
    int age;
    double score;
} Stu;

int main() {
    FILE *fp = NULL;
    
    // 以读写模式打开文件
    if ((fp = fopen("test.txt", "w+")) == NULL) {
        perror("fopen error");
        return -1;
    }
    
    // 写入三个学生数据
    Stu students[] = {
        {"张三", 18, 98.0},
        {"李四", 20, 88.0},
        {"王五", 16, 95.0}
    };
    fwrite(students, sizeof(Stu), 3, fp);
    
    // 获取文件大小
    fseek(fp, 0, SEEK_END);
    printf("文件大小: %ld 字节\n", ftell(fp));
    
    // 移动光标到第二个学生
    fseek(fp, sizeof(Stu), SEEK_SET);
    
    // 读取并显示第二个学生信息
    Stu temp;
    if (fread(&temp, sizeof(Stu), 1, fp) == 1) {
        printf("姓名: %s, 年龄: %d, 成绩: %.2f\n", temp.name, temp.age, temp.score);
    }
    
    fclose(fp);
    return 0;
}

说明

  • 光标操作fseek灵活控制文件读取位置,ftell可用于计算文件大小。
  • 重置光标rewind适合在同一文件流中从头重新读取。
  • 注意:二进制文件操作时,偏移量需与数据结构大小对齐。

总结与注意事项

  • 文件操作流程:始终检查fopen返回值,确保文件打开成功;操作完成后使用fclose关闭文件。
  • 错误处理:使用perror或检查返回值捕获错误,确保程序健壮性。
  • 缓冲区管理:写入数据后可用fflush刷新缓冲区,确保数据及时写入。
  • 安全性:优先使用snprintf而非sprintf,避免缓冲区溢出。
  • 跨平台注意:二进制文件读写需考虑字节序和结构体对齐问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2402404.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-select 实现分页加载,切换也数滚回到顶部,自定义高度

el-select 实现分页加载&#xff0c;切换也数滚回到顶部&#xff0c;自定义高度 1.html <el-form-item label"俱乐部&#xff1a;" prop"club_id" label-width"120px"><el-select :disabled"Boolean(match_id)" style"w…

Langchaine4j 流式输出 (6)

Langchaine4j 流式输出 大模型的流式输出是指大模型在生成文本或其他类型的数据时&#xff0c;不是等到整个生成过程完成后再一次性 返回所有内容&#xff0c;而是生成一部分就立即发送一部分给用户或下游系统&#xff0c;以逐步、逐块的方式返回结果。 这样&#xff0c;用户…

学习经验分享【40】目标检测热力图制作

目标检测热力图在学术论文&#xff08;尤其是计算机视觉、深度学习领域&#xff09;中是重要的可视化分析工具和论证辅助手段&#xff0c;可以给论文加分不少。主要作用一是增强论文的可解释性与说服力&#xff1a;论文中常需解释模型 “如何” 或 “为何” 检测到目标&#xf…

C#里与嵌入式系统W5500网络通讯(3)

有与W5500通讯时,需要使用下面的寄存器: PHYCFGR (W5500 PHY Configuration Register) [R/W] [0x002E] [0b10111XXX] PHYCFGR configures PHY operation mode and resets PHY. In addition, PHYCFGR indicates the status of PHY such as duplex, Speed, Link. 这张表格详细…

用OpenNI2获取奥比中光Astra Pro输出的深度图(win,linux arm64 x64平台)

搞了一个奥比中光Astra Pro&#xff0c;想在windows平台&#xff0c;和linux rk3588 &#xff08;香橙派&#xff0c;ubuntu2404,debian)上获取深度信息&#xff0c;之前的驱动下载已经不好用了,参考如下 Astra 3D相机选型建议 - 知乎https://zhuanlan.zhihu.com/p/594485674 …

Unity VR/MR开发-VR设备与适用场景分析

视频讲解链接&#xff1a;【XR马斯维】VR/MR设备与适用场景分析&#xff1f;【UnityVR/MR开发教程--入门】_游戏热门视频

Linux: network: switch:arp cache更新规则 [chatGPT]

文章目录 介绍概念普通包带有不同的mac,是否更新arp cache?普通包带有相同的mac,是否刷新 aging timeswitch是否会主动学习介绍 关于arp cache在switch侧的行为。有很多问题需要理解。 概念 HP L3 - IP Services Configuration Guide 文档里有写:dynamic arp entry的解说…

Java网络编程API 1

Java中的网络编程API一共有两套&#xff1a;一套是UDP协议使用的API&#xff1b;另一套是TCP协议使用的API。这篇文章我们先来介绍UDP版本的API&#xff0c;并尝试来写一个回显服务器&#xff08;接收到的请求是什么&#xff0c;返回的响应就是什么&#xff09;。 UDP数据报套…

兰亭妙微 | 医疗软件的界面设计能有多专业?

从医疗影像系统到手术机器人控制界面&#xff0c;从便携式病原体检测设备到多平台协同操作系统&#xff0c;兰亭妙微为众多医疗设备研发企业&#xff0c;打造了兼具专业性与可用性的交互界面方案。 我们不仅做设计&#xff0c;更深入理解医疗场景的实际需求&#xff1a; 对精…

前端原生构建交互式进度步骤组件(Progress Steps)

在现代网页设计中&#xff0c;进度步骤&#xff08;Progress Steps&#xff09; 是一种常见的 UI 模式&#xff0c;常用于引导用户完成注册流程、多步表单、教程或任何需要分步骤操作的场景。本文将带你从零开始构建一个美观且功能完整的 “进度步骤”组件&#xff0c;并详细讲…

【基于阿里云搭建数据仓库(离线)】Data Studio创建资源与函数

Data Studio支持在您的数据分析代码中引用自定义的资源和函数&#xff08;支持MaxCompute、EMR、CDH、Flink&#xff09;&#xff0c;您需要先创建或上传资源、函数至目标工作空间&#xff0c;上传后才可在该工作空间的任务中使用。您可参考本文了解如何使用DataWorks可视化方式…

web3-以太坊智能合约基础(理解智能合约Solidity)

以太坊智能合约基础&#xff08;理解智能合约/Solidity&#xff09; 无需编程经验&#xff0c;也可以帮助你了解Solidity独特的部分&#xff1b;如果本身就有相应的编程经验如java&#xff0c;python等那么学起来也会非常的轻松 一、Solidity和EVM字节码 实际上以太坊链上储存…

【C++项目】负载均衡在线OJ系统-2

文章目录 oj_server模块编写oj_server框架的搭建-oj_server/oj_server.cpp 路由框架 oj_model模块编写题目信息设置v1.文件版本-common/util.hpp boost库spilt函数的使用-oj_server/oj_model_file.hpp 文件版本model编写v2.mysql数据库版本1.mysql创建授权用户、建库建表录入操…

GC1809:高性能24bit/192kHz音频接收芯片解析

1. 芯片概述 GC1809 是数字音频接收芯片&#xff0c;支持IEC60958、S/PDIF、AES3等协议&#xff0c;集成8选1输入切换、低抖动时钟恢复和24bit DAC&#xff0c;适用于家庭影院、汽车音响等高保真场景。 核心特性 高精度&#xff1a;24bit分辨率&#xff0c;动态范围105dB&…

2025年06月05日Github流行趋势

项目名称&#xff1a;onlook 项目地址url&#xff1a;https://github.com/onlook-dev/onlook项目语言&#xff1a;TypeScript历史star数&#xff1a;16165今日star数&#xff1a;1757项目维护者&#xff1a;Kitenite, drfarrell, spartan-vutrannguyen, apps/devin-ai-integrat…

基于BI PaaS架构的衡石HENGSHI SENSE平台技术解析:重塑企业级数据分析基座

在数据驱动决策的时代&#xff0c;传统BI工具日益显露出扩展性弱、灵活性差、资源利用率低等痛点。衡石科技推出的HENGSHI SENSE平台&#xff0c;创新性地采用BI PaaS&#xff08;平台即服务&#xff09;架构&#xff0c;为企业构建了一个强大、开放、可扩展的数据分析基础设施…

【R语言编程绘图-plotly】

安装与加载 在R中使用plotly库前需要安装并加载。安装可以通过CRAN进行&#xff0c;使用install.packages()函数。加载库使用library()函数。 install.packages("plotly") library(plotly)测试库文件安装情况 # 安装并加载必要的包 if (!requireNamespace("p…

通信刚需,AI联手ethernet/ip转profinet网关打通工业技术难关

工业人工智能&#xff1a;食品和饮料制造商的实际用例通信刚需 了解食品饮料制造商如何利用人工智能克服业务挑战 食品和饮料制造商正面临劳动力短缺、需求快速变化、运营复杂性加剧以及通胀压力等挑战。如今&#xff0c;生产商比以往任何时候都更需要以更少的投入实现更高的…

JavaEE->多线程:定时器

定时器 约定一个时间&#xff0c;时间到了&#xff0c;执行某个代码逻辑&#xff08;进行网络通信时常见&#xff09; 客户端给服务器发送请求 之后就需要等待 服务器的响应&#xff0c;客户端不可能无限的等&#xff0c;需要一个最大的期限。这里“等待的最大时间”可以用定时…

<el-table>构建树形结构

最佳实践 el-table实现树形结构主要依靠row-key和tree-props来实现的。 &#x1f4ab; 无论是el-table实现的树形结构还是el-tree组件都是绑定的树形结构的数据&#xff0c;因此如果数据是扁平的话&#xff0c;需要进行树化。 代码 <template><div><el-table:d…