当前位置: 首页 > web >正文

文件基础-----C语言经典题目(10)

一.标准 io 和文件 io 有什么区别,分别在什么场景下使用?

        标准 io 和文件 io 是两种不同的输入输出处理方式。

标准 I/O

  特点:

                基于(Stream)的操作,使用缓冲机制,提高读写效率。

                有printf、scanf、fgets、fputs等接口。

                自动处理文本和二进制模式的差异。

                跨平台兼容性好。

  使用场景:

                用户交互。

                处理文本文件。

                需要缓冲提高性能的场景。

                不需要底层文件控制的场景。

int main() 
{// 打开文件"test.txt",使用写入模式("w")// 如果文件不存在则创建,如果存在则清空内容FILE *fp = fopen("test.txt", "w");// 检查文件是否成功打开if (fp != NULL) {// 使用fprintf向文件流写入格式化字符串// 相当于printf,但输出目标是文件而非控制台fprintf(fp, "Hello, World!\n");// 关闭文件流,释放资源// 重要:避免内存泄漏和数据丢失fclose(fp);}return 0;
}

文件 I/O 系统调用

  特点:

                基于文件描述符(整数)的操作,直接调用操作系统的系统调用(open、read、write、close)。

                无缓冲,每次操作直接与文件系统交互。

                提供底层控制,如文件定位、权限设置等。

  使用场景:

                对性能要求极高的场景。

                底层文件操作。(设备驱动

                处理二进制文件(多媒体数据)。                

int main() 
{// 打开文件"test.txt",使用以下标志:// O_WRONLY: 只写模式// O_CREAT: 如果文件不存在则创建// 0644: 文件权限(用户可读可写,组和其他用户可读)int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);// 检查文件是否成功打开(返回值为文件描述符,-1表示失败)if (fd != -1) {const char *msg = "Hello, World!\n";// 写入数据到文件// 参数:文件描述符、数据指针、数据长度// 返回值:实际写入的字节数,-1表示错误write(fd, msg, strlen(msg));// 关闭文件描述符,释放资源// 重要:避免文件描述符泄漏close(fd);}return 0;
}

二.标准io 是否带有缓存机制,系统提供标准 io 的缓存机制有哪些,以及各自的特性?

        标准 io库是带有缓存机制的,目的是减少系统调用的次数,提高程序的运行效率。

全缓冲:

        当缓存区被填满或者执行刷新操作(调用fflush)时,才会进行实际的 io 操作,适用于对磁盘文件的操作。

        特点:当缓冲区满或者调用 fflush、程序正常终止时,才会进行实际的读写操作。

        默认情况:标准库通常会为磁盘文件设置大约 8kb 的缓冲区。

行缓冲:

        当遇到换行符 \n 或者缓冲区被填满、执行刷新操作时,才会进行实际的 io 操作。

        特点:标准io 默认采用行缓冲。

无缓冲:

        所有的 io 操作都会立即执行,不会进行缓存。标准错误输出(stderr)通常使用这种缓冲机制,能保证错误详细能够及时显示出来。

缓冲类型设置方法:

        可以使用 setvbuf 函数来设置流的缓冲类型,函数原型为:

int setvbuf(FILE *stream, char *buf, int mode, size_t size);

其中,mode 的取值有:

        _IOFBF:全缓冲。

        _IOLBF:行缓冲。

        _IONBF:无缓冲。

缓存刷新的触发条件:

        1.缓冲区满,自动刷新缓存。

        2.调用 fflush 函数可以强制刷新缓存。

        3.程序正常终止时,会刷新所有缓存。

        4.对于行缓冲,遇到换行符 \n 时会刷新缓存。

int main() 
{// 将stdout设置为全缓冲setvbuf(stdout, NULL, _IOFBF, 1024);printf("This is fully buffered output."); // 不会立即显示// 将stdout设置为行缓冲setvbuf(stdout, NULL, _IOLBF, 1024);printf("This is line buffered output.\n"); // 遇到\n会显示// 将stdout设置为无缓冲setvbuf(stdout, NULL, _IONBF, 0);printf("This is unbuffered output."); // 立即显示return 0;
}

三.linux 中,文件的类型有哪些?

        文件类型借助文件属性来划分,可以通过 stat 结构体以及相关宏定义对这些类型进行判断。

普通文件:

        用于存储数据的文件,涵盖文本文件、二进制文件等。

        可以通过 S_ISREG(mode)宏来判断。

目录文件:

        用于存储文件系统的结构,包含其他文件和目录的相关信息。

        用 S_ISDIR(mode)来判断。

字符设备文件:

        代表着字符设备,比如终端、串口之类的。

        用 S_ISCHR(mode)宏来判断。

块设备文件:

        代表着块设备,比如硬盘、U 盘等

        用 S_ISBLK(mode)来判断。

套接字文件:

        用于进程间的网络通信

        用 S_ISSOCK(mode)来判断。

符号链接文件:

        是指向其他文件或目录的一种特殊文件

        用 S_ISLNK(mode)来判断。

命名管道文件:

        用于进程间的通信,

        用 S_ISFIFO(mode)来判断。

判断文件类型:

int main(int argc, char *argv[]) 
{struct stat fileStat;// 检查命令行参数,确保用户提供了文件名if (argc != 2) {printf("Usage: %s <filename>\n", argv[0]);return 1;}// 获取文件状态信息// stat函数通过文件名获取文件的详细信息,存储在fileStat结构体中if (stat(argv[1], &fileStat) < 0) {perror("stat");  // 打印错误信息return 1;}// 输出文件的基本信息printf("文件类型信息:\n");printf("设备ID: %ld\n", (long)fileStat.st_dev);    // 包含文件的设备IDprintf("inode: %ld\n", (long)fileStat.st_ino);      // 文件的inode号// 使用宏判断文件类型并输出结果if (S_ISREG(fileStat.st_mode))printf("类型:普通文件\n");if (S_ISDIR(fileStat.st_mode))printf("类型:目录\n");if (S_ISCHR(fileStat.st_mode))printf("类型:字符设备文件\n");if (S_ISBLK(fileStat.st_mode))printf("类型:块设备文件\n");if (S_ISFIFO(fileStat.st_mode))printf("类型:命名管道文件\n");if (S_ISLNK(fileStat.st_mode))printf("类型:符号链接文件\n");if (S_ISSOCK(fileStat.st_mode))printf("类型:套接字文件\n");return 0;
}

四.linux 程序开发过程中,使用的 stdio.h 这个头文件在系统的哪个目录下可以找到?

        stdio.h 头文件一般存于标准 C 库的头文件目录。

        /usr/include :是系统默认的头文件搜索路径,在编译程序是,编译器会自动搜索该目录。

可以用以下命令来搜索:

find /usr/include -name "stdio.h"
# 或者使用 locate 命令(需要先执行 updatedb)
locate stdio.h
# 还可以通过 gcc 命令查看搜索路径
gcc -print-file-name=stdio.h

 

五.系统编程过程怎么查询手册?

        一般就是使用 linux 系统的 man 命令。

基本用法:

man [章节号] 函数名/系统调用名

查询 open 函数:

man open

查询 read 函数的第 2 章节(系统调用):

man 2 read

手册章节说明: 

1.用户命令(ls、grep)

2.系统调用(open、read)

3.库函数(printf、malloc)

4.设备文件和驱动

5.文件格式(/etc/passwd格式)

6.游戏和娱乐

7.杂项(宏、协议)

8.系统管理命令(mount、ifconfig)

六.标准 io 中 文件操作的操作方法有哪些?

1.文件打开与关闭

        FILE *fopen(const char  *filename,const  char  *mode):打开文件并返回文件指针,mode 参数指定打开模式(“r” 读,“w”写,“a”追加)。

        int  fclose(FILE  *stream):关闭文件流,释放资源。

2.按字符读写

        int  fgetc(FILE  *stream):从文件读取一个字符,返回 EOF 表示文件结束。

        int  fputc(int  c,FILE  *stream):向文件写入一个字符。

3.按行读写

        char  *fgets(char  *s,int  size,FILE  *stream):读取一行(最多 size - 1字符)到字符串 s,自动添加 \0。

        int  fputs(const  char  *s,FILE  *stream):向文件写入字符串(不自动添加换行符)。

4.格式化读写

        int  fprintf(FILE  *stream,const  char  *format,......):格式化输出到文件,类似 printf。

        int  fscanf(FILE  *stream,const  char  *format,......):从文件格式化输入,类似scanf。

int main() 
{FILE *fp;           // 定义文件指针,用于操作文件char buffer[100];   // 缓冲区,用于存储从文件读取的数据// 打开文件(写模式)// "w" 表示写入模式,如果文件不存在则创建,存在则清空内容fp = fopen("test.txt", "w");// 检查文件是否成功打开if (fp == NULL) {perror("无法打开文件");  // perror 输出系统错误信息return 1;              // 返回非零值表示程序异常退出}// 写入数据到文件fprintf(fp, "Hello, World!\n");  // 格式化输出,类似 printffputs("This is a test file.\n", fp);  // 写入字符串(不带换行符)fclose(fp);  // 关闭文件,释放资源// 打开文件(读模式)// "r" 表示只读模式,文件必须存在fp = fopen("test.txt", "r");// 再次检查文件是否成功打开if (fp == NULL)     {perror("无法打开文件");return 1;}// 读取文件内容并打印到控制台// fgets 返回 NULL 表示已到达文件末尾或发生错误while (fgets(buffer, sizeof(buffer), fp) != NULL) {printf("%s", buffer);  // 打印读取的一行数据}fclose(fp);  // 关闭文件return 0;    // 返回 0 表示程序正常退出
}

七.文件 io 中文件操作的操作方法有哪些?

        文件 io 操作主要依靠标准库(stdio.h)来实现。

1.文件打开与关闭

        fopen():打开文件,返回一个 FILE 指针。

FILE *fopen(const char *filename, const char *mode);
// 示例
FILE *fp = fopen("example.txt", "r"); // 以只读模式打开文件

        fclose():关闭文件,释放资源。

int fclose(FILE *stream);
// 示例
fclose(fp);

2.字符读写

        fgetc()  /  getc():从文件中读取单个字符。

int fgetc(FILE *stream);
// 示例
int c = fgetc(fp);

        fputc()  /  putc():从文件中写入单个字符。

int fputc(int c, FILE *stream);
// 示例
fputc('A', fp);

3.字符串读写

        fgets():从文件读取一行字符串。

char *fgets(char *str, int n, FILE *stream);
// 示例
char buffer[100];
fgets(buffer, 100, fp);

        fputs():向文件写入字符串。

int fputs(const char *str, FILE *stream);
// 示例
fputs("Hello, World!", fp);

4.格式化读写

        fscanf():按格式从文件读取数据。

int fscanf(FILE *stream, const char *format, ...);
// 示例
int num;
fscanf(fp, "%d", &num);

        fprintf():按格式向文件写入数据。

int fprintf(FILE *stream, const char *format, ...);
// 示例
fprintf(fp, "%d", 42);

5.二进制读写

        fread():从文件读取二进制数据。

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
// 示例
int arr[10];
fread(arr, sizeof(int), 10, fp);

        fwrite():向文件写入二进制数据。

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
// 示例
fwrite(arr, sizeof(int), 10, fp);

6.文件模式

        “r”:只读,文件必须存在。

        “w”:写入,若文件存在则清空,不存在则创建。

        “a”:追加,在文件末尾添加内容。

        “r+”:读写,文件必须存在。

        “w+”:读写,若文件存在则清空,不存在则创建。

        “a+”:读写,在文件末尾添加内容,可读取整个文件。

八.文件读写操作过程中,文本文件和二进制文件有什么区别?

存储形式:

  文本文件:以 ASCII 码的形式来存储字符,每个字节代表一个字符,比如数字 1  2  3,就会被存成 3 个字节,分别对应字符 “1” (49)、   "2"   (50)   、 "3"(51)。

  二进制文件:数据按照在内存中的存储形式直接写入文件。比如一个 int 类型的数字 123在内存中占 4 个字节,就会原封不动地将这 4 个字节写入文件,而不会进行字符转换。 

读写函数:

  文本文件:一般使用 fprintf()、fscanf()、fgets()、fputs()等函数进行读写操作。这些函数在处理数据时会自动进行格式转换。

  二进制文件:主要用 fread()和 fwrite()函数来读写。这两个函数是按对数据进行操作的,不会对数据格式进行转换。

换行符处理

  文本文件:换行符 \n。使用文本模式进行读写时,系统会自动完成换行符的转换。

  二进制文件:会原样保留所有数据,不会对换行符进行转换。

文件打开模式

  文本文件:使用 'r' 、‘w’、‘a’等。

  二进制文件:要在模式后加 ‘b’,例如 ‘rb’、‘wb’、‘ab’,来明确指定使用二进制模式。

数据完整性

  文本文件:由于存在格式转换,在存储一些特殊数据,如浮点数、二进制数据时,有可能造成精度丢失。

  二进制文件:能够完整保留数据的原始格式,适合用来存储图像、音频、结构体等数据。

int main() 
{int n = 123;// === 文本文件操作 ===// 以文本写入模式打开文件("w")// 若文件不存在则创建,存在则清空内容FILE *txt_file = fopen("text.txt", "w");// 使用fprintf以文本格式写入数据// 将整数123转换为字符串"123"存储// 占用3个字节,分别对应字符'1'、'2'、'3'fprintf(txt_file, "%d", n);// 关闭文件,释放资源fclose(txt_file);// === 二进制文件操作 ===// 以二进制写入模式打开文件("wb")// 同样若文件不存在则创建,存在则清空FILE *bin_file = fopen("binary.bin", "wb");// 使用fwrite直接写入内存中的二进制数据// &n:获取变量n的内存地址// sizeof(int):每个数据项的大小(4字节)// 1:写入1个数据项// 直接存储整数123的二进制表示(如0x0000007B)fwrite(&n, sizeof(int), 1, bin_file);// 关闭文件fclose(bin_file);// === 验证区别 ===// text.txt文件内容(文本查看):123// binary.bin文件内容(二进制查看):7B 00 00 00(取决于系统字节序)return 0;
}

http://www.xdnf.cn/news/3037.html

相关文章:

  • 前端Vue3 + 后端Spring Boot,前端取消请求后端处理逻辑分析
  • 第35周Zookkeeper+Dubbo Zookkeeper
  • Transformer数学推导——Q32 可学习位置编码的梯度更新公式推导
  • Arkts完成数据请求http以及使用axios第三方库
  • 杭州数据库恢复公司之Dell服务器RAID5阵列两块硬盘损坏报警离线
  • 服务器远程超出最大连接数的解决方案是什么?
  • 如何创建并使用极狐GitLab 项目访问令牌?
  • 基于esp32的小区智能门禁集成系统设计和实现
  • BFS最短路
  • Vue + ECharts 实现多层极坐标环形图
  • 基于STM32、HAL库的ATECC508A安全验证及加密芯片驱动程序设计
  • java练习2
  • langchain 简单与ollama 关联使用
  • Thinkphp开发自适应职业学生证书查询系统职业资格等级会员证书管理网站
  • SMPP协议解析
  • mysql数据库连接数不足导致 Bean 注入失败
  • 4月28号
  • TCP三次握手
  • [TxRxResult] There is no status packet! 及 Incorrect status packet! 问题修复
  • 第一章 应急响应- Linux入侵排查
  • 文件基础-----C语言经典题目(11)
  • 前端vue2修改echarts字体为思源黑体-避免侵权-可以更换为任意字体统一管理
  • Linux 权限管理
  • API文档生成与测试工具推荐
  • 提示词工程实战指南:解锁AI创作的隐藏技巧与实例
  • AI驱动全流程基于PLUS-InVEST模型的生态系统服务多情景智能模拟与土地利用优化、论文写作
  • Python3: 函数式编程特性
  • 基于Spring Boot 电商书城平台系统设计与实现(源码+文档+部署讲解)
  • Day16(贪心算法)——LeetCode45.跳跃游戏II763.划分字母区间
  • 异步IO与Tortoise-ORM的数据库