问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C语言I/O操作详解:从基础到进阶

创作时间:
作者:
@小白创作中心

C语言I/O操作详解:从基础到进阶

引用
CSDN
1.
https://blog.csdn.net/weidl001/article/details/139730766

C语言的输入输出(I/O)操作是程序与外部环境交互的重要手段。通过I/O操作,程序可以读取用户输入、访问文件系统以及输出结果到屏幕或文件。本文将详细介绍C语言中的I/O操作,包括文件与目录操作、字符流与字节流、序列化与反序列化及新的I/O(NIO)等内容,帮助读者全面理解和掌握C语言中的I/O操作。

一、文件与目录操作

文件与目录操作是C语言中最常见的I/O操作之一。C语言提供了一组标准库函数,便于程序员对文件和目录进行创建、读写和删除等操作。

  1. 打开与关闭文件

在C语言中,使用fopen函数打开文件,使用fclose函数关闭文件。文件可以以不同的模式打开,如读、写、追加等。

示例代码:

#include <stdio.h>
int main() {
    FILE *file;
    
    // 以读模式打开文件
    file = fopen("example.txt", "r");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    
    // 关闭文件
    fclose(file);
    return 0;
}
  1. 文件读写操作

C语言中提供了多种文件读写函数,如fscanffprintffgetsfputs等。

示例代码:

#include <stdio.h>
int main() {
    FILE *file;
    char buffer[100];
    // 写入文件
    file = fopen("example.txt", "w");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    fprintf(file, "Hello, world!\n");
    fclose(file);
    // 读取文件
    file = fopen("example.txt", "r");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    fgets(buffer, 100, file);
    printf("读取到的内容: %s", buffer);
    fclose(file);
    return 0;
}
  1. 文件定位与错误处理

C语言提供了文件指针定位函数(如fseekftellrewind)及错误处理函数(如ferrorclearerr)。

示例代码:

#include <stdio.h>
int main() {
    FILE *file;
    long pos;
    // 以读模式打开文件
    file = fopen("example.txt", "r");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    // 移动文件指针到文件末尾
    fseek(file, 0, SEEK_END);
    // 获取文件指针位置
    pos = ftell(file);
    printf("文件大小: %ld 字节\n", pos);
    // 关闭文件
    fclose(file);
    return 0;
}

二、字符流与字节流

字符流和字节流是处理数据流的两种基本方式。字符流处理文本数据,而字节流处理二进制数据。

  1. 字符流处理

字符流适用于处理文本文件,通过函数如fgetcfputcfgetsfputs等进行操作。

示例代码:

#include <stdio.h>
int main() {
    FILE *file;
    char ch;
    // 以读模式打开文件
    file = fopen("example.txt", "r");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    // 逐字符读取文件
    while ((ch = fgetc(file)) != EOF) {
        putchar(ch);
    }
    // 关闭文件
    fclose(file);
    return 0;
}
  1. 字节流处理

字节流适用于处理二进制文件,通过函数如freadfwrite操作。

示例代码:

#include <stdio.h>
int main() {
    FILE *file;
    int buffer[5] = {1, 2, 3, 4, 5};
    // 写入二进制文件
    file = fopen("data.bin", "wb");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    fwrite(buffer, sizeof(int), 5, file);
    fclose(file);
    // 读取二进制文件
    file = fopen("data.bin", "rb");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    fread(buffer, sizeof(int), 5, file);
    for (int i = 0; i < 5; i++) {
        printf("buffer[%d] = %d\n", i, buffer[i]);
    }
    fclose(file);
    return 0;
}

三、序列化与反序列化

序列化是将对象转换为字节流的过程,以便存储或传输数据;反序列化是将字节流转换为对象的过程。C语言通过自定义函数实现序列化和反序列化。

  1. 序列化

序列化的目的是将数据结构转换为二进制格式,以便存储到文件或通过网络传输。

示例代码:

#include <stdio.h>
typedef struct {
    int id;
    char name[50];
} Person;
void serialize(Person *person, FILE *file) {
    fwrite(person, sizeof(Person), 1, file);
}
int main() {
    Person person = {1, "John Doe"};
    FILE *file = fopen("person.dat", "wb");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    serialize(&person, file);
    fclose(file);
    return 0;
}

在上面的示例代码中,我们定义了一个Person结构体,并通过serialize函数将其写入到二进制文件person.dat中。

  1. 反序列化

反序列化的目的是将二进制格式的数据转换回原来的数据结构。

示例代码:

#include <stdio.h>
typedef struct {
    int id;
    char name[50];
} Person;
void deserialize(Person *person, FILE *file) {
    fread(person, sizeof(Person), 1, file);
}
int main() {
    Person person;
    FILE *file = fopen("person.dat", "rb");
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    deserialize(&person, file);
    fclose(file);
    printf("ID: %d, Name: %s\n", person.id, person.name);
    return 0;
}

在上面的示例代码中,我们通过deserialize函数从二进制文件person.dat中读取数据,并将其转换回Person结构体。

四、新的I/O(NIO)

新的I/O(NIO)是一种改进的I/O处理方式,通常通过第三方库实现。NIO提高了数据处理的性能和效率,尤其在大规模数据处理和网络应用中。然而,C语言标准库中不包含NIO实现,但可以借助操作系统提供的系统调用及第三方库(如libuv、Boost.Asio)实现NIO。

表格总结

操作
函数
示例
打开文件
fopen
file = fopen("example.txt", "r");
关闭文件
fclose
fclose(file);
读写文本文件
fscanffprintffgetsfputs
fscanf(file, "%d", &num);
文件定位
fseekftellrewind
fseek(file, 0, SEEK_END);
类型
操作
函数
示例
字符流
读取字符
fgetc
ch = fgetc(file);
字符流
写入字符
fputc
fputc(ch, file);
字符流
读取字符串
fgets
fgets(buffer, 100, file);
字符流
写入字符串
fputs
fputs(buffer, file);
字节流
读取字节
fread
fread(buffer, size, count, file);
字节流
写入字节
fwrite
fwrite(buffer, size, count, file);
操作
函数
示例
序列化
fwrite
fwrite(person, sizeof(Person), 1, file);
反序列化
fread
fread(person, sizeof(Person), 1, file);

总结

输入输出(I/O)操作在C语言编程中占据重要地位,包括文件与目录操作、字符流与字节流处理,以及序列化与反序列化。通过深入理解和掌握这些I/O操作,程序员可以实现与外部环境的高效数据交互,为各种应用场景提供稳定可靠的解决方案。无论是文本文件的读写、二进制数据的处理,还是复杂数据结构的序列化和反序列化,这些I/O操作的掌握都对编写高效、健壮的C程序至关重要。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号