文件 io

笔记 · 2024-08-29 · 153 人浏览

  常用的文件I/O函数及其基本用法。

函数用法 IOFILE.c

#include <stdio.h>

#define FILENAME_IO ("io.txt")
#define FILENAME_TX ("text.txt")
#define TEXT_PUTS (" litter noob..\n")
#define TEXT_PRINTF ("Justin_Wu")
#define BUF_MAX_SIZE (100)

int main(int argc, char const *argv[])
{
    /*
     * char *__restrict __filename:  字符串表示要打开的文件名称
     * char *__restrict __modes:访问模式
     *   (1)r:只读模式 如果没有文件会报错
     *   (2)w:只写模式 如果文件存在清空文件 如果不存在创建新文件
     *   (3)a:只追加写模式 如果文件存在末尾追加写 如果不存在创建新文件
     *   (4)r+:读写模式 文件必须存在 写入是从头一个一个覆盖
     *   (5)w+:读写模式 如果文件存在清空文件 如果不存在创建新文件
     *   (6)a+:读追加写模式 如果文件存在末尾追加写 如果不存在创建新文件
     * return:FILE * 结构体指针 表示一个文件
     *         报错返回 NULL
     * FILE *fopen (const char *__restrict __filename,
             const char *__restrict __modes)
     */
    FILE * iofile = fopen((char *)FILENAME_IO, "a+"); 
    if (iofile == NULL)
    {
        printf("Not File!\n");    
    }
    else
    {
        printf("Opened Success!\n");
    }

    /** int fputc (int __c, FILE *__stream);
     *  int __c:ASCII码对应的char
     *  FILE *__stream:打开的一个文件
     *  return:成功返回对于的char 失败返回EOF
     *  读写权限记录在fopen方法中的参数
     */
    int put_result = fputc(97, iofile);
    if (put_result == EOF)
    {
        printf("Writed Word is File!\n");
    }
    else 
    {
        printf("Writed '%c' !\n", put_result);
    }

    /** fputs (const char *__restrict __s, FILE *__restrict __stream);
     *  char *__restrict __s:需要写入的字符串
     *  FILE *__restrict __stream:需要写入的文件
     *  return:成功返回非法整数(0, 1) 失败返回EOF
     *  读写权限记录在fopen方法中的参数
     */
    int puts_result = fputs((char *)TEXT_PUTS, iofile);
    if (put_result == EOF)
    {
        printf("Writed Word is File!\n");
    }
    else 
    {
        printf("Writed Word is Success!\n");
    }

    /** fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...)
     *  FILE *__restrict __stream:需要打开的文件
     *  const char *__restrict __s:带格式化的长字符串
     *  ... 可变参数:填入格式化的长字符串
     *  return:成功返回写入的字符的个数 不包含换行符 失败返回EOF
     */
    int printf_result = fprintf(iofile, "This is a fprintf\n\t\t%s", TEXT_PRINTF);
    if (printf_result == EOF)
    {
        printf("Writed Word is File!\n");
    }
    else 
    {
        printf("Writed Word is Success!\n");
    }

    /** int fgetc (FILE *__stream);
     *  FILE *__stream:需要打开的文件
     *  return:成功返回读取到的一个字节 如果失败返回EOF(出错或者文件的末尾)
     */
    FILE * iofile_tx = fopen((char *)FILENAME_TX, "r");
    while (fgetc(iofile_tx) != EOF)
    {
        printf("%c", fgetc(iofile_tx));
    }
    printf("\n");

    /** char * fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
     * 读取文件的内容
     *  char *__restrict __s:接收读取到的字符串
     *  int __n:接收数据的长度 
     *  FILE *__restrict __stream:打开要读取的文件
     *  return:成功返回读取到字符串 如果失败返回NULL,可以直接使用while
     */
    char buf[BUF_MAX_SIZE];
    while (fgets(buf, sizeof(buf), iofile_tx))
    {
        // 光标已经移到最后,打印为空
        printf("%s", buf);
    }

    /** int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...)
     *  FILE *__restrict __stream:打开的文件
     *  char *__restrict __format:带格式化的字符串(固定格式接收)
     *  ... 可变参数:填写格式化的字符串(接收数据提前声明的变量)
     *  return:成功匹配到的参数个数,如果批评失败返回0 报错或者文件结束EOF
     */
    char name[50];
    int age;
    char wife[50];
    int scanf_result = fscanf(iofile, "%s %d %s", name, &age, wife);
    if (scanf_result != EOF)
    {
        printf("Success!\n");
    }
    else 
    {
        printf("MATCH:%d,Road File!\n", scanf_result);
    }

    /** int fclose (FILE *__stream);
     *  FILE *__stream:需要关闭的文件
     *  return: 成功返回 0 失败返回EOF(负数)通常关闭文件失败会直接报错
     */
    int result = fclose(iofile);
    if (result == EOF)
    {
        printf("Closed FAIL!\n");
    }
    else if (!result)
    {
        fclose(iofile_tx);
        printf("Closed Success!\n");
    }
    else
    {
        printf("Not File!\n");    
    }

    return 0;
}

标准输入/输出/错误 stdin_out_err_test.c

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

#define BUF_SIZE (sizeof(char) * 100)

int main()
{
    char * buf = (char *)malloc(BUF_SIZE);

    // 从标准输入中读取数据
    fgets(buf, BUF_SIZE, stdin);
    printf("buf:%s\n", buf);
    return 0;    

    // 标准输出
    fputs(buf, stdout);
    printf("\n");

    // 错误输出
    fputs(buf, stderr);
    printf("\n");

    free(buf);
}

系统调用 unixstdio.c

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#define FILE_NAME "io.txt"
#define BUF_SIZE 1024

int main()
{
    /**  int open (const char *__path, int __oflag, ...);
     *  const char *__path: 文件路径
     *  int __oflag: 用于指定打开文件的方式,可以是以下选项的组合:
     *     (1) O_RDONLY: 以只读方式打开文件 
     *     (2) O_WRONLY: 以只写方式打开文件 
     *     (3) O_RDWR: 以读写方式打开文件 
     *     (4) O_CREAT: 如果文件不存在,则创建一个新文件 
     *     (5) O_APPEND: 将所有写入操作追加到文件的末尾 
     *     (6) O_TRUNC: 如果文件存在并且以写入模式打开,则截断文件长度为0 
     *     还有其他标志,如O_EXCL(当与O_CREAT一起使用时,只有当文件不存在时才创建新文件)、O_SYNC(同步I/O)、O_NONBLOCK(非阻塞I/O)等 
     *  可选参数: mode -> 仅在使用了O_CREAT标志且文件尚不存在的情况下生效,用于指定新创建文件的权限位 权限位通常由三位八进制数字组成,分别代表文件所有者、同组用户和其他用户的读写执行权限
     *  return: (1) 成功时返回非负的文件描述符。
     *         (2) 失败时返回-1,并设置全局变量errno以指示错误原因。
    */
    // Linux操作系统有文件保护权限,默认创建的文件会被删除掉其它用户的写权限   
    int fd = open(FILE_NAME, O_RDONLY | O_CREAT, 0755);
    if (fd == -1)
    {
        perror("open");
        return -1;
    }

    /** ssize_t read (int __fd, void *__buf, size_t __nbytes);
     *  int __fd: 一个整数,表示要从中读取数据的文件描述符
     *  void *__buf: 一个指向缓冲区的指针,读取的数据将被存放到这个缓冲区中:
     *  size_t __nbytes:一个size_t类型的整数,表示要读取的最大字节数 系统调用将尝试读取最多这么多字节的数据,
     *                   但实际读取的字节数可能会少于请求的数量
     *  return: (1) 成功时,read()返回实际读取的字节数 这个值可能小于__nbytes,
     *              如果遇到了文件结尾(EOF)或者因为网络读取等原因提前结束读取 
     *         (2) 失败时,read()将返回-1
    */

    char buf[BUF_SIZE];
    int ret = read(fd, buf, sizeof(buf));
    if (ret == -1)
    {
        perror("read");
        return -1;
    }
    printf("read data: %s\n", buf);

    /** ssize_t write (int __fd, const void *__buf, size_t __n);
     *  int __fd: 一个整数,表示要将数据写入到的文件描述符
     *  const void *__buf: 一个指向缓冲区的指针,写入的数据需要先存放到这个缓冲区中
     *  size_t __n:一个size_t类型的整数,表示要写入的字节数 write()函数会尝试写入__n个字节的数据,
     *              但实际写入的字节数可能会少于请求的数量
     *  return: (1) 成功时,write()返回实际写入的字节数 这个值可能小于__n,如果写入操作因故提前结束,
     *                 例如: 磁盘满、网络阻塞等情况 
                (2) 失败时,write()将返回-1
     */

    ret = write(fd, buf, sizeof(buf));
    if (ret == -1)
    {
        perror("write");
        return -1;
    }

    /** int close (int __fd);
     *  int __fd:一个整数,表示要关闭的文件描述符
     *  return: (1) 成功关闭时 返回0
                (2) 失败时 返回-1
     */

    ret = close(fd);
    if (ret == -1)
    {
        perror("close");
        return -1;
    }

    /**
     * 立即终止当前进程,且不进行正常的清理操作,如关闭文件、释放内存等。
     * 这个函数通常在程序遇到严重错误需要立即退出时使用,或者在某些情况下希望避免清理工作时调用。
     * void _exit (int status);
     * void _Exit (int __status);
     * 
     * void exit (int status);
     * 终止当前进程,但是在此之前会执行3种清理操作
     * (1) 调用所有通过atexit()注册的终止处理函数(自定义)
     * (2) 刷新所有标准I/O缓冲区(刷写缓存到文件)
     * (3) 关闭所有打开的标准I/O流(比如通过fopen打开的文件)

     * int status: 父进程可接收到的退出状态码 0表示成功 非0表示各种不同的错误
     */

    _exit(0);

    return 0;
}

使用 MakeFile

gcc := CC
IOFILE: IOFILE.c
    -$(CC) -o $@ $^ 
    -./$@
    -rm ./$@

stdin_out_err_test: stdin_out_err_test.c
    -$(CC) -o $@ $^ 
    -./$@
    -rm ./$@

unixstdio: unixstdio.c
    -$(CC) -o $@ $^ 
    -./$@
    -rm ./$@
C
Theme Jasmine by Kent Liao

本网站由 又拍云 提供CDN加速/云存储服务

鄂ICP备2023005457号    鄂公网安备 42011302000815号