• Linux文件编程详解


    Linux文件编程详解

    Ubuntu(Linux)系统下进行文件操作涉及一系列的系统调用,这些调用是基于Unix风格的文件操作API。这些操作包括打开或创建文件、从文件中读取数据、向文件中写入数据、移动文件指针以及关闭文件。以下是这些函数的详细介绍和实际应用示例。

    1. 创建和打开文件 (open)

    open 函数简介

    open 函数用于打开一个现有文件或创建一个新文件。当配合 O_CREAT 标志使用时,它可以创建一个新的文件。

    函数原型
    1. #include
    2. #include
    3. #include
    4. int open(const char *pathname, int flags, ... /* mode_t mode */);
    • 参数说明

    • pathname: 要打开或创建的文件的路径。
    • flags: 控制文件打开或创建方式的标志,可以是:
      • O_RDONLY:只读打开。
      • O_WRONLY:只写打开。
      • O_RDWR:读写打开。
      • O_CREAT:如果文件不存在,则创建它。
      • O_EXCL:与 O_CREAT 一起使用时,如果文件已存在,则返回错误。
      • O_TRUNC:如果文件已存在并且是以写入方式打开,则清空文件。
    • mode (可选参数):指定新文件的权限。这个参数是在文件创建时设置的,通常与 umask 的默认设置一起使用,例如 06440755 等。
     示例代码:创建文件
    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main() {
    7. int fd; // 文件描述符
    8. // 创建文件,如果文件不存在。设置文件权限为 0644 (rw-r--r--)
    9. fd = open("newfile.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    10. if (fd == -1) {
    11. perror("创建文件失败");
    12. exit(EXIT_FAILURE);
    13. }
    14. printf("文件 'newfile.txt' 已成功创建\n");
    15. // 对文件进行写操作等
    16. // ...
    17. // 完成操作后,关闭文件
    18. close(fd);
    19. return 0;
    20. }

    2. 写入文件 (write)

    write 函数将数据写入文件。

    函数原型
    1. #include
    2. ssize_t write(int fd, const void *buf, size_t count);
    • fd:文件描述符,由 open 返回。
    • buf:指向数据缓冲区的指针。
    • count:要写入的字节数。
     示例代码:写入数据
    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main() {
    7. int fd;
    8. fd = open("testfile.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
    9. if (fd == -1) {
    10. perror("打开文件失败");
    11. exit(EXIT_FAILURE);
    12. }
    13. char *data = "Hello, Ubuntu 文件编程!";
    14. // 将字符串数据写入文件
    15. if (write(fd, data, strlen(data)) == -1) {
    16. perror("写入文件失败");
    17. close(fd);
    18. exit(EXIT_FAILURE);
    19. }
    20. printf("数据写入成功\n");
    21. // 写入完毕,关闭文件
    22. close(fd);
    23. return 0;
    24. }

     3. 读取文件(read)

    参数说明

    • fd:文件描述符,表示要读取数据的文件。这个文件描述符通常是通过 open 系统调用获取的。
    • buf:指向数据缓冲区的指针,用于存储从文件中读取的数据。
    • count:指定要读取的最大字节数。实际读取的字节数可能少于这个值,比如文件剩余内容不足 count 字节时。

    返回值

    • 返回读取的字节数,如果文件已到达末尾,则返回 0。
    • 如果发生错误,则返回 -1,并设置 errno 以指示错误类型。
    函数原型:
    1. #include
    2. ssize_t read(int fd, void *buf, size_t count);

    示例代码: 

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main() {
    6. int fd; // 文件描述符
    7. ssize_t bytes_read; // 实际读取的字节数
    8. char buffer[1024]; // 数据缓冲区
    9. // 打开文件
    10. fd = open("example.txt", O_RDONLY);
    11. if (fd == -1) {
    12. perror("打开文件失败");
    13. exit(EXIT_FAILURE);
    14. }
    15. // 从文件中读取数据
    16. bytes_read = read(fd, buffer, sizeof(buffer) - 1); // 保留一个位置用于放置字符串终止符'\0'
    17. if (bytes_read == -1) {
    18. perror("读取文件失败");
    19. close(fd);
    20. exit(EXIT_FAILURE);
    21. }
    22. buffer[bytes_read] = '\0'; // 确保读取的内容被正确终止以便作为字符串处理
    23. // 打印读取的内容
    24. printf("读取到的内容:\n%s\n", buffer);
    25. // 关闭文件
    26. close(fd);
    27. return 0;
    28. }

    4. 关闭文件 (close)

    close 函数用于关闭一个打开的文件描述符,释放系统资源。

    函数原型
    1. #include
    2. int close(int fd);

    fd:要关闭的文件描述符。

    关闭文件的重要性 

    关闭文件是必要的,因为打开的文件描述符是有限的资源。每个进程能打开的文件数量是有限的,未及时关闭文件可能导致资源泄漏,影响程序性能或导致程序异常。

    5. 移动文件 (lseek)

    lseek 函数用于移动文件的读/写指针到指定位置。

    函数原型
    1. #include
    2. #include
    3. off_t lseek(int fd, off_t offset, int whence);
    • fd:文件描述符。
    • offset:偏移量,可为负值。
    • whence:起始位置(SEEK_SET 从文件开始,SEEK_CUR 从当前位置,SEEK_END 从文件末尾)。
     移动文件光标使用 lseek 系统调用。下面是一个示例代码:
    1. #include
    2. #include
    3. #include
    4. #include
    5. #define FILENAME "example.txt"
    6. int main() {
    7. // 以只读模式打开文件 example.txt
    8. int fd = open(FILENAME, O_RDONLY);
    9. if (fd == -1) {
    10. // 打开文件失败,输出错误信息并退出程序
    11. perror("open");
    12. exit(EXIT_FAILURE);
    13. }
    14. // 将文件光标移动到文件末尾,并获取文件大小
    15. off_t offset = lseek(fd, 0, SEEK_END);
    16. if (offset == -1) {
    17. // lseek操作失败,输出错误信息并关闭文件描述符
    18. perror("lseek");
    19. close(fd);
    20. exit(EXIT_FAILURE);
    21. }
    22. // 打印文件大小
    23. printf("文件大小: %ld 字节\n", offset);
    24. // 将文件光标移动回文件开头
    25. if (lseek(fd, 0, SEEK_SET) == -1) {
    26. // lseek操作失败,输出错误信息并关闭文件描述符
    27. perror("lseek");
    28. close(fd);
    29. exit(EXIT_FAILURE);
    30. }
    31. // 关闭文件描述符
    32. close(fd);
    33. return 0;
    34. }

    6. 计算文件大小(lseek)

    计算文件大小可以使用 lseek 系统调用将文件光标移动到文件末尾,然后获取当前位置的偏移量。下面是一个示例代码:
    1. #include
    2. #include
    3. #include
    4. #include
    5. #define FILENAME "example.txt"
    6. int main() {
    7. // 以只读模式打开文件 example.txt
    8. int fd = open(FILENAME, O_RDONLY);
    9. if (fd == -1) {
    10. // 打开文件失败,输出错误信息并退出程序
    11. perror("open");
    12. exit(EXIT_FAILURE);
    13. }
    14. // 将文件光标移动到文件末尾,并获取文件大小
    15. off_t file_size = lseek(fd, 0, SEEK_END);
    16. if (file_size == -1) {
    17. // lseek操作失败,输出错误信息并关闭文件描述符
    18. perror("lseek");
    19. close(fd);
    20. exit(EXIT_FAILURE);
    21. }
    22. // 打印文件大小
    23. printf("文件大小: %ld 字节\n", file_size);
    24. // 关闭文件描述符
    25. close(fd);
    26. return 0;
    27. }

    7打开/创建文件打开/创建文件

    7.cp文件的实现

    mian函数参数的用法
    1. #include
    2. int main(int argc,char **argv)
    3. {
    4. printf("total params:%d\n",argc);
    5. printf("No.1 params :%s\n",argv[0]);
    6. printf("No.2 params :%s\n",argv[1]);
    7. printf("No.3 params :%s\n",argv[2]);
    8. return 0;
    9. }

    argc :代表的是 ./a.out argc argv 这三个参数的个数

    argv[0] :代表第一个参数./a.out

    argv[1] :代表第二个参数 argc

    argv[2] :代表第二个参数 argv

    由此可见argv是数组的数组。

    思路:1.打开源文件src.c

    ​ 2.读src到buf

    ​ 3.打开/创建目标文件des.c

    ​ 4.将buf写入des.c

    ​ 5.close两个文件

    1. #include // 引入类型定义,如pid_t等
    2. #include // 引入文件状态定义,如S_IRUSR等
    3. #include // 引入文件控制定义,如O_RDWR等
    4. #include // 引入标准输入输出库,用于printf等函数
    5. #include // 引入POSIX操作系统API,如read、write等
    6. #include // 引入字符串操作库,用于strlen等函数
    7. #include // 引入标准库,用于malloc、exit等函数
    8. int main(int argc, char **argv)
    9. {
    10. int fdSrc; // 源文件的文件描述符
    11. int fdDes; // 目标文件的文件描述符
    12. char *readBuf=NULL; // 用于存储从源文件读取的数据
    13. if(argc != 3){ // 检查命令行参数数量是否正确
    14. printf("pararm error\n"); // 参数错误时打印错误信息
    15. exit(-1); // 错误退出程序
    16. }
    17. fdSrc = open(argv[1], O_RDWR); // 以读写方式打开源文件
    18. int size = lseek(fdSrc, 0, SEEK_END); // 定位到源文件的末尾,获取文件大小
    19. lseek(fdSrc, 0, SEEK_SET); // 重新定位到文件开头,准备读取数据
    20. readBuf = (char *)malloc(sizeof(char) * size + 8); // 分配足够的内存以存储文件数据,额外加8字节防止溢出
    21. int n_read = read(fdSrc, readBuf, size); // 从源文件读取数据到缓冲区
    22. fdDes = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0600); // 以读写方式打开或创建目标文件,若文件存在则长度截为0
    23. int n_write = write(fdDes, readBuf, strlen(readBuf)); // 将读取的数据写入目标文件,使用strlen确保只写入有效字符串长度
    24. close(fdSrc); // 关闭源文件
    25. close(fdDes); // 关闭目标文件
    26. return 0; // 程序正常结束
    27. }

     8.文件编程修改程序的配置文件demo

    1. #include // 引入用于系统调用的基本数据类型
    2. #include // 引入用于文件属性操作的定义
    3. #include // 引入用于文件控制的函数定义
    4. #include // 引入标准输入输出库
    5. #include // 引入POSIX操作系统API
    6. #include // 引入字符串操作函数
    7. #include // 引入标准库函数
    8. int main(int argc, char **argv)
    9. {
    10. int fdSrc; // 定义源文件的文件描述符
    11. char *readBuf = NULL; // 定义读取数据的缓冲区指针
    12. if(argc != 2){ // 检查输入参数是否为2个,不正确则报错
    13. printf("parameter error\n"); // 打印参数错误信息
    14. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    15. }
    16. // 以读写模式打开源文件,文件描述符保存在fdSrc中
    17. fdSrc = open(argv[1], O_RDWR);
    18. if (fdSrc == -1) { // 检查文件是否成功打开
    19. perror("Error opening file"); // 打印错误信息
    20. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    21. }
    22. // 使用lseek获取文件大小
    23. int size = lseek(fdSrc, 0, SEEK_END);
    24. if (size == -1) { // 检查是否成功获取文件大小
    25. perror("Error seeking file"); // 打印错误信息
    26. close(fdSrc); // 关闭文件
    27. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    28. }
    29. // 将文件指针重新定位到文件开始
    30. if (lseek(fdSrc, 0, SEEK_SET) == -1) {
    31. perror("Error re-seeking file"); // 打印错误信息
    32. close(fdSrc); // 关闭文件
    33. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    34. }
    35. // 分配内存以存储文件数据,多分配8字节防止溢出
    36. readBuf = (char *)malloc(sizeof(char) * size + 8);
    37. if (readBuf == NULL) { // 检查内存分配是否成功
    38. perror("Memory allocation failed"); // 打印错误信息
    39. close(fdSrc); // 关闭文件
    40. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    41. }
    42. // 从文件中读取数据到缓冲区
    43. int n_read = read(fdSrc, readBuf, size);
    44. if (n_read == -1) { // 检查读取是否成功
    45. perror("Error reading file"); // 打印错误信息
    46. free(readBuf); // 释放内存
    47. close(fdSrc); // 关闭文件
    48. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    49. }
    50. // 查找特定的字符串"LENG=",准备修改其后的值
    51. char *p = strstr(readBuf, "LENG=");
    52. if (p == NULL) { // 检查是否找到指定字符串
    53. printf("not found\n"); // 打印未找到信息
    54. free(readBuf); // 释放内存
    55. close(fdSrc); // 关闭文件
    56. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    57. }
    58. // 修改找到字符串后的值
    59. p += strlen("LENG=");
    60. *p = '5'; // 设置新的值为'5'
    61. // 将文件指针重新定位到文件开始
    62. if (lseek(fdSrc, 0, SEEK_SET) == -1) {
    63. perror("Error re-seeking file"); // 打印错误信息
    64. free(readBuf); // 释放内存
    65. close(fdSrc); // 关闭文件
    66. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    67. }
    68. // 将修改后的缓冲区内容写回文件
    69. int n_write = write(fdSrc, readBuf, strlen(readBuf));
    70. if (n_write == -1) { // 检查写入是否成功
    71. perror("Error writing file"); // 打印错误信息
    72. free(readBuf); // 释放内存
    73. close(fdSrc); // 关闭文件
    74. exit(EXIT_FAILURE); // 退出程序,返回失败标志
    75. }
    76. // 释放内存并关闭文件描述符
    77. free(readByf);
    78. close(fdSrc);
    79. return 0; // 返回成功
    80. }

    9.写一个整数到文件和写结构体数组到文件

    示例程序 1: 写入和读取单个整数
    1. #include // 引入用于系统调用的基本数据类型
    2. #include // 引入用于文件属性操作的定义
    3. #include // 引入用于文件控制的函数定义
    4. #include // 引入标准输入输出库
    5. #include // 引入POSIX操作系统API
    6. #include // 引入字符串操作函数
    7. #include // 引入标准库函数
    8. int main()
    9. {
    10. int fd; // 文件描述符
    11. int data = 100; // 要写入文件的整数
    12. int data2 = 0; // 用于读取文件数据的整数
    13. fd = open("./file1",O_RDWR); // 打开文件以读写方式
    14. int n_write = write(fd,&data,sizeof(int)); // 将整数data写入文件
    15. lseek(fd,0,SEEK_SET); // 重置文件指针到文件开始处
    16. int n_read = read(fd, &data2, sizeof(int)); // 从文件读取整数到data2
    17. printf("read %d \n",data2); // 打印读取的整数
    18. close(fd); // 关闭文件描述符
    19. return 0; // 程序正常退出
    20. }
    示例程序 2: 写入和读取单个结构体
    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. struct Test // 定义一个结构体,包含一个整数和一个字符
    9. {
    10. int a;
    11. char c;
    12. };
    13. int main()
    14. {
    15. int fd; // 文件描述符
    16. struct Test data = {100,'a'}; // 初始化结构体变量data
    17. struct Hest data2; // 用于读取文件数据的结构体变量
    18. fd = open("./file1",O_RDWR); // 打开文件以读写方式
    19. int n_write = write(fd,&data,sizeof(struct Test)); // 将结构体data写入文件
    20. lseek(fd,0,SEEK_SET); // 重置文件指针到文件开始处
    21. int n_read = read(fd, &data2, sizeof(struct Test)); // 从文件读取结构体到data2
    22. printf("read %d,%c \n",data2.a,data2.c); // 打印读取的结构体内容
    23. close(fd); // 关闭文件描述符
    24. return 0; // 程序正常退出
    25. }
    示例程序 3: 写入和读取结构体数组
    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. struct Test // 定义一个结构体,包含一个整数和一个字符
    9. {
    10. int a;
    11. char c;
    12. };
    13. int main()
    14. {
    15. int fd; // 文件描述符
    16. struct Test data[2] = {{100,'a'},{101,'b'}}; // 初始化结构体数组
    17. struct Test data2[2]; // 用于读取文件数据的结构体数组
    18. fd = open("./file1",O_RDWR); // 打开文件以读写方式
    19. int n_write = write(fd,&data,sizeof(struct Test)*2); // 将结构体数组data写入文件
    20. lseek(fd,0,SEEK_SET); // 重置文件指针到文件开始处
    21. int n_read = read(fd, &data2, sizeof(struct Test)*2); // 从文件读取结构体数组到data2
    22. printf("read %d,%c \n",data2[0].a,data2[0].c); // 打印读取的第一个结构体内容
    23. printf("read %d,%c \n",data2[1].a,data2[1].c); // 打印读取的第二个结构体内容
    24. close(fd); // 关闭文件描述符
    25. return 0; // 程序正常退出
    26. }

    10.open和fopen区别

    openfopen 是用于文件操作的两个常见函数,它们存在一些关键差异,主要体现在它们所属的库和API风格、功能、以及使用场景上。

     1. 来源

    从来源的角度看,两者能很好的区分开,这也是两者最显而易见的区别:

    • open是UNIX系统调用函数(包括LINUX等),返回的是文件描述符(File Descriptor),它是文件在文件描述符表里的索引。
    • fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调用不同的内核api。返回的是一个指向文件结构的指针。 
       PS:从来源来看,两者是有千丝万缕的联系的,毕竟C语言的库函数还是需要调用系统API实现的。
    2. 移植性

    这一点从上面的来源就可以推断出来,`fopen`是C标准函数,因此拥有良好的移植性;而`open`是UNIX系统调用,移植性有限。如windows下相似的功能使用API函数`CreateFile`。

    3. 适用范围
    • open返回文件描述符,而文件描述符是UNIX系统下的一个重要概念,UNIX下的一切设备都是以文件的形式操作。如网络套接字、硬件设备等。当然包括操作普通正规文件(Regular File)。
    • fopen是用来操纵普通正规文件(Regular File)的。
    4. 文件IO层次

    如果从文件IO的角度来看,前者属于低级IO函数,后者属于高级IO函数。低级和高级的简单区分标准是:谁离系统内核更近。低级文件IO运行在内核态,高级文件IO运行在用户态。

    5. 缓冲
    1. 缓冲文件系统 
      缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用;当执行读文件的操作时,从磁盘文件将数据先读入内存“缓冲区”,装满后再从内存“缓冲区”依此读出需要的数据。执行写文件的操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存“缓冲区”的大小,影响着实际操作外存的次数,内存“缓冲区”越大,则操作外存的次数就少,执行速度就快、效率高。一般来说,文件“缓冲区”的大小随机器 而定。fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等。
    2. 非缓冲文件系统 
      缓冲文件系统是借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,既可以读写字符、字符串、格式化数据,也可以读写二进制数据。非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件,但效率高、速度快,由于ANSI标准不再包括非缓冲文件系统,因此建议大家最好不要选择它。open, close, read, write, getc, getchar, putc, putchar等。

    一句话总结一下,就是open无缓冲,fopen有缓冲。前者与readwrite等配合使用, 后者与fread,fwrite等配合使用。

    使用fopen函数,由于在用户态下就有了缓冲,因此进行文件读写操作的时候就减少了用户态和内核态的切换(切换到内核态调用还是需要调用系统调用API:readwrite);而使用open函数,在文件读写时则每次都需要进行内核态和用户态的切换;表现为,如果顺序访问文件,fopen系列的函数要比直接调用open系列的函数快;如果随机访问文件则相反。

    这样一总结梳理,相信大家对于两个函数及系列函数有了一个更全面清晰的认识,也应该知道在什么场合下使用什么样的函数更合适,效率更高。

     使用 open 示例:
    1. #include // 引入文件控制的头文件
    2. #include // 引入POSIX操作系统API
    3. #include // 引入文件状态的头文件
    4. #include // 引入标准输入输出库
    5. #include // 引入标准库,用于使用exit等函数
    6. int main() {
    7. // 以写入、创建、截断方式打开文件,文件权限为用户读写
    8. int fd = open("example.dat", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    9. if (fd == -1) {
    10. perror("Failed to open file"); // 打开文件失败时输出错误信息
    11. exit(EXIT_FAILURE); // 退出程序
    12. }
    13. const char *text = "Hello, world!"; // 定义要写入的字符串
    14. if (write(fd, text, 13) != 13) { // 写入字符串到文件
    15. perror("Failed to write"); // 写入失败时输出错误信息
    16. close(fd); // 关闭文件描述符
    17. exit(EXIT_FAILURE); // 退出程序
    18. }
    19. close(fd); // 成功写入后关闭文件描述符
    20. return 0;
    21. }
    使用 fopen 示例:
    1. #include // 引入标准输入输出库
    2. #include // 引入标准库,用于使用exit等函数
    3. int main() {
    4. // 以写入模式打开文件
    5. FILE *fp = fopen("example.txt", "w");
    6. if (fp == NULL) {
    7. perror("Failed to open file"); // 打开文件失败时输出错误信息
    8. exit(EXIT_FAILURE); // 退出程序
    9. }
    10. const char *integer = "Hello, world!"; // 定义要写入的字符串
    11. if (fprintf(fp, "%s", integer) < 0) { // 使用fprintf将字符串写入文件
    12. perror("Failed to write"); // 写入失败时输出错误信息
    13. fclose(fp); // 关闭文件流
    14. exit(EXIT_FAILURE); // 退出程序
    15. }
    16. fclose(fp); // 成功写入后关闭文件流
    17. return 0;
    18. }

    11.标准C库打开C库打开创建文件读写文件光标移动

    1. #include // 引入标准输入输出库,用于文件操作和基本的输入输出功能
    2. #include // 引入字符串处理库,用于处理字符串,如计算字符串长度等
    3. int main()
    4. {
    5. FILE *fp; // 声明一个 FILE 类型的指针,用于表示文件流
    6. char *str = "hello world"; // 声明并初始化一个字符串常量,将用于写入文件
    7. char readBuf[128] = {0}; // 声明一个字符数组作为读取缓冲区,并初始化所有元素为 0
    8. fp = fopen("./hello.txt","w+"); // 使用 fopen 函数以读写模式打开(如果不存在则创建)一个名为 chen.txt 的文件
    9. // 使用 fwrite 函数将字符串 str 写入文件
    10. // str: 要写入的数据的指针
    11. // sizeof(char)*strlen(str): 每个数据单元的大小乘以要写入的数据单元的数量,这里计算整个字符串的总大小
    12. // 1: 写入的数据块数量,这里写入一次整个字符串
    13. // fp: 目标文件流的指针
    14. fwrite(str, sizeof(char)*strlen(str), 1, fp);
    15. fseek(fp, 0, SEEK_SET); // 使用 fseek 函数将文件内的位置指针重新定位到文件开头
    16. // 使用 fread 函数从文件中读取数据
    17. // readBuf: 用于接收数据的缓冲区的指针
    18. // sizeof(char)*strlen(str): 每个数据单元的大小乘以数据单元的数量,这里计算整个字符串的总大小
    19. // 1: 读取的数据块数量,这里读取一次整个字符串
    20. // fp: 源文件流的指针
    21. fread(readModule, sizeof(char)*strlen(str), 1, fp);
    22. printf("read data: %s\n", readBuf); // 使用 printf 函数打印读取到的数据
    23. return 0; // 程序正常结束,返回 0
    24. }

     12.第一个程序:写入并读取字符串  第二个程序:写入并读取结构体

    1. #include // 引入标准输入输出库
    2. #include // 引入字符串处理库
    3. int main() {
    4. FILE *fp; // 文件指针
    5. char *str = "hello world"; // 要写入文件的字符串
    6. char readBuf[128] = {0}; // 读取数据的缓冲区,初始化为0
    7. fp = fopen("./hello.txt", "w+"); // 以读写模式打开文件,如果文件不存在则创建
    8. if (fp == NULL) { // 文件打开失败的处理
    9. perror("Failed to open file");
    10. return -1;
    11. }
    12. int nwrite = fwrite(str, sizeof(char) * strlen(str), 1, fp); // 将字符串写入文件
    13. fseek(fp, 0, SEEK_SET); // 重置文件指针到文件开头
    14. int nread = fread(readBuf, sizeof(char) * strlen(str), 100, fp); // 从文件读取数据到缓冲区
    15. printf("read data: %s\n", readBuf); // 打印读取的数据
    16. printf("read=%d, write = %d\n", nread, nwrite); // 打印读取和写入的数据数量
    17. return 0; // 程序结束
    18. }
    1. #include // 引入标准输入输出库
    2. #include // 引入系统类型定义
    3. #include // 引入文件状态控制库
    4. #include // 引入文件控制函数库
    5. #include // 引入POSIX操作系统API
    6. #include // 引入字符串处理库
    7. #include // 引入标准库函数
    8. struct Test {
    9. int a; // 结构体的整型成员
    10. char c; // 结构体的字符成员
    11. };
    12. int main() {
    13. FILE *fp; // 文件指针
    14. struct Test data = {100, 'a'}; // 初始化结构体实例
    15. struct Test data2; // 用于存储从文件读取的结构体数据
    16. fp = fopen("./file1", "w+"); // 以读写模式打开文件
    17. if (fp == NULL) { // 文件打开失败的处理
    18. perror("Failed to open file");
    19. return -1;
    20. }
    21. int n_write = fwrite(&data, sizeof(struct Test), 1, fp); // 将结构体写入文件
    22. fseek(fp, 0, SEEK_SET); // 重置文件指针到文件开头
    23. int n_read = fread(&data2, sizeof(struct Test), 1, fp); // 从文件读取结构体数据
    24. printf("read %d,%c \n", data2.a, data2.c); // 打印读取的结构体成员
    25. fclose(fp); // 关闭文件
    26. return 0; // 程序结束
    27. }
    第一个程序:向文件中写入字符串
    1. #include // 引入标净输入输出库
    2. #include // 引入字符串处理库
    3. int main()
    4. {
    5. FILE *fp; // 文件指针
    6. int i; // 循环计数器
    7. char *str = "zlb hen shuai o!"; // 要写入文件的字符串
    8. int len = strlen(str); // 计算字符串的长度
    9. fp = fopen("./test.txt", "w+"); // 以读写模式打开文件,如果文件不存在则创建
    10. if (fp == NULL) { // 文件打开失败的处理
    11. perror("Failed to open file");
    12. return -1;
    13. }
    14. for (i = 0; i < len; i++) { // 遍历字符串中的每个字符
    15. fputc(*str, fp); // 将当前字符写入文件
    16. str++; // 移动到字符串的下一个字符
    17. }
    18. fclose(fp); // 关闭文件
    19. return 0;
    20. }
    第二个程序:从文件中读取字符串
    1. #include // 引入标准输入输出库
    2. #include // 引入字符串处理库
    3. int main()
    4. {
    5. FILE *fp; // 文件指针
    6. int i; // 循环计数器
    7. char c; // 用于存储读取的字符
    8. fp = fopen("./test.txt", "r"); // 以只读模式打开文件
    9. if (fp == NULL) { // 文件打开失败的处理
    10. perror("Failed to open file");
    11. return -1;
    12. }
    13. while (!feof(fp)) { // 判断文件是否结束
    14. c = fgetc(fp); // 从文件中读取一个字符
    15. printf("%c", c); // 打印读取的字符
    16. }
    17. fclose(fp); // 关闭文件
    18. return 0;
    19. }

     

  • 相关阅读:
    flink调优之RocksDB设置
    leetcode面试题0808有重复字符串的排列组合
    Java8 Stream流
    西门子S7-200SMART 通过向导实现S7通信的具体组态步骤示例
    【曹工杂谈】 2021在鹅厂干了一年,我的一些感悟
    电脑小技巧45个
    西电计科院微机原理与系统设计课程笔记(车向泉版)
    C语言学习书籍(提高篇)
    for...of与for...in
    SQL触发器
  • 原文地址:https://blog.csdn.net/ITQWQ/article/details/139780666