进击的NDK04-文件IO、预编译

读取文本文件

void main(){
    char *path = "J:\\User.xml";
    //打开
    FILE *fp =fopen(path, "r");
    
    if (fp == NULL){
        printf("文件打开失败");
        return;
    }

    //读取s
    char buff[50];//缓冲
    while (fgets(buff, 50, fp)){
        printf("%s", buff);
    }
    fclose(fp);

    getchar();
}

写入文本文件

void main(){
    char * path = "J:\\hello.txt";
    FILE *fp = fopen(path, "w");


    char *text = "2018年9月12日 21:17:44";
    fputs(text, fp);
    
    fclose(fp);
    getchar();
}

计算机的文件存储在物理上都是二进制

文本文件和二进制之分,其实是一个逻辑之分
C读写文本文件与二进制文件的差别仅仅体现在回车换行符
写文本时,每遇到一个'\n',会将其转换成'\r\n'(回车换行)
读文本时,每遇到一个'\r\n',会将其转换成'\n'

文件复制

void main(){
    char *readPath = "J:\\1.jpg";
    char *writePath = "J:\\2.jpg";
        //r读的文件 b字符表示操作二进制文件binary
        FILE *read_fp = fopen(readPath, "rb");
        //写的文件
        FILE * write_fp = fopen(writePath, "wb");
        //复制
        int buff[50]; //缓冲区域
        int len = 0; //每次读到的数据长度
        while ((len = fread(buff, sizeof(int), 50, read_fp)) != 0){
            //将读到的内容写入新的文件
            fwrite(buff, sizeof(int), len, write_fp);
        }
        //关闭流
        fclose(read_fp);
        fclose(write_fp);
        getchar();
}

获取文件的大小

void main(){
    char *read_path = "J:\\1.jpg";
    FILE *fp = fopen(read_path, "r");
    //重新定位文件指针
    //SEEK_END文件末尾,0偏移量
    fseek(fp, 0, SEEK_END);
    //返回当前的文件指针,相对于文件开头的位移量
    long filesize = ftell(fp);
    printf("%d\n", filesize);

    getchar();
}

预编译

c语言执行的流程

  1. 编译:形成目标代码(.obj)。
  2. 连接:将目标代码与c函数库链接合并,连接器负责找到这个函数的实现,形成最终的可执行文件。
  3. 执行

宏定义

定义标识

#ifdef __cplusplus 标识支持C++语法

可以解决互相引入问题

A.h

A.h头文件引入B.h头文件


#include "B.h"

void printfA();

B.h

B.h头文件又引入A.h头文件

#include "A.h"

void printfB();

c1.c

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

#include "A.h"

void printfA(){
    printf("Hello printfA");
}

void main(){
    
    printfA();
    getchar();
}

这里会报 error C1014: 包含文件太多 : 深度 = 1024,这是因为A.hB.h循环引入导致的错误。

可以通过定义标识解决该问题。

A.h

#ifndef AH
#define AH
#include "B.h"

void printfA();
#endif

B.h

#ifndef BH
#define BH
#include "A.h"

void printfB();

#endif

tip:这里有更加简单的写法

A.h

//该头文件只被包含一次,让编译器自定处理好循环包含问题
#pragma once
#include "B.h"

void printfA();

B.h

#pragma once
#include "A.h"

void printfB();

定义常数

#define PI 3.14

定义宏函数

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

//定义读写两个函数
void file_read(){
    printf("file_read \n");
}

void file_write(){
    printf("file_write \n");
}

//定义宏函数,OPERATE代表参数
//当函数很长的时候可以使用宏函数缩短函数的名称
#define file(OPERATE) file_##OPERATE();

void main(){

    //输出file_read,等于执行file_read函数
    file(read);
    
    //输出file_write,等于执行file_write函数
    file(write);

    getchar();
}

除了可以像上面替换函数名之外,还可以传参数到宏函数中。以输出日志为例:

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

//LEVEL 是日志的级别
//FORMAT是数据格式化的方式,使用的时候用 ##FORMAT代替
//... 代表可变参数,使用的时候用__VA_ARGS__ 代替
#define LOG(LEVEL,FORMAT,...) printf(##LEVEL);printf(##FORMAT,__VA_ARGS__);
#define LOG_I(FORMAT,...) LOG("INFO:",##FORMAT,__VA_ARGS__);
#define LOG_W(FORMAT,...) LOG("WARING",##FORMAT,__VA_ARGS__);
#define LOG_E(FORMAT,...) LOG("ERROR",##FORMAT,__VA_ARGS__);

void main(){
    
    LOG_I("%s%s", "大小:", "89 \n");
    LOG_W("%s%s", "大小:", "89 \n");
    LOG_E("%s%s", "大小:", "89 \n");
    getchar();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 广义上的二进制文件包括文本文件,这里讨论的是狭义上的二进制文件与文本文件的比较: 1. 能存储的数据类型不同 文本...
    时待吾阅读 14,069评论 2 28
  • 一、快捷键 ctr+b 执行ctr+/ 单行注释ctr+c ...
    o_8319阅读 11,110评论 2 16
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 14,193评论 2 33
  • .bat脚本基本命令语法 目录 批处理的常见命令(未列举的命令还比较多,请查阅帮助信息) 1、REM 和 :: 2...
    庆庆庆庆庆阅读 12,602评论 1 19
  • github地址 github地址 github地址 http://www.cocoachina.com/ios/...
    乂滥好人阅读 949评论 0 0