本人大一学生,以下文章作为学习笔记用于加深记忆和复习,并分享给其他需要的人.
内容不含标准概念,更容易理解.
内容面向c语言初学者
代码执行之前的事情,命令以#开头
头文件
是C语言的宏定义,本质是替换,会在预处理阶段对程序中所有出现的"宏名"的地方进行替换
#define 宏名 内容
#define PI 3.14159 //定义PI为3.14159 相当于给常量起名
#define NUM 3+1
int main(){
int n = NUM * NUM; //拆解 : 3 + 1 * 3 + 1
printf("n = %d\n", n); //结果 : 7
return 0;
}
#define 宏名(形参列表) 内容
#define ADD(a,b) a+b
#include
// #define 宏名(形参列表) 内容
#define ADD(a,b) a+b
#define ADD1(a,b) (a+b)
// 注意:没有参数类型 没有返回值 本质:替换
int main()
{
// 拆解: n = a + b ;
int n = ADD(1,2); // 拆解: 1 + 2
printf("n = %d\n", n); // 结果: 3
n = ADD(1, ADD(5, 6))*ADD(3, 4); // 拆解: 1 + 5 + 6 * 3 + 4
printf("n = %d\n", n); // 结果: 28
n = ADD1(1, ADD1(5, 6))*ADD1(3, 4); // 拆解: ( 1 + (5 + 6) ) * (3 + 4)
printf("n = %d\n", n); // 结果: 84
double d = ADD(1.223, 2.456); // 拆解: 1.223 + 2.456
printf("d = %lf\n", d); // 结果: 3.679000
return 0;
}
#ifdef 宏名
代码块;
#endif
根据宏名是否定义,如果定义了,就会执行代码块直到endif,否则不执行代码块
#include
#define def_1 1; // 宏定义 def_1
int main()
{
#ifdef AAA // 判断 def_1 宏名以被定义 执行代码块内容
printf("宏名以被定义\n");
#endif // AAA // 结束宏判断
return 0;
}
#include
#define def_1 1 // 宏定义 def_1
int main() {
#ifdef def_1 // 判断是否定义宏名 def_1
printf("以定义宏名 def_1"); // 结果
#else
printf("未定义宏名 def_1");
#endif
return 0;
}
#ifndef 宏名
代码块;
#else
代码块;
#endif
根据宏名是否定义,如果没有定义,就会执行相对代码直到endif,否则不执行代码块
#include
#define def_1 1 // 宏定义 def_1
int main() {
#ifndef def_1 // 判断是否定义宏名 def_1
printf("未定义宏名 def_1");
#else
printf("以定义宏名 def_1"); // 结果
#endif
return 0;
}
令某代码永远只执行一次:
#ifndef def_1
#define def_1
//代码块
#endif
#if(表达式)
// 代码块1;
#else
// 代码块2;
#endif
如果表达式为真 , 执行代码块 1 ,否则执行代码块 2.
#include
int main() {
#if(1)
printf("yes\n");
#else
printf("no\n");
#endif
return 0;
}
文件的后缀名: .docx .txt .c .cpp .exe .bat .csv …
名字.后缀
1 相对路径: 从当前项目开始到目标文件
2 绝对路径: 从根目录开始到目标文件
以: 路径 + 名字.后缀 来确定文件
更多内容参考:https://www.runoob.com/cprogramming/c-file-io.html
1、定义文件指针 FILE*file;
2、open(“路径”,“打开方式”)打开文件
3、文件的打开方式
“r”(只读) 为了输入数据,打开一个已存在的文本文件 出错
“w”(只写) 为了输出数据,打开一个文本文件 新建文件
“a”(追加) 向文本文件尾部添加数据 出错
“rb”(只读) 为了输入数据,打开一个已存在的二进制文件 出错
“wb”(只写) 为了输出数据,打开一个二进制文件 新建文件
“ab”(追加) 向二进制文件尾部添加数据 出错
“r+”(读写) 为了读和写,打开一个文本文件 出错
“w+”(读写) 为了读和写,打开一个文本文件 新建文件
“a+”(读写) 为了读和写,打开一个文本文件 出错
“rb+”(读写) 为了读和写,打开一个二进制文件 出错
“wb+”(读写) 为了读和写,打开一个二进制文件 新建文件
“ab+”(读写) 为了读和写,打开一个二进制文件 出错
4、fclose()关闭文件
5、fgetc(文件指针) 读取一个字符
6、fputc(字符,文件指针) 写入一个字符
7、fgets(字符指针,大小,文件指针) 读取一行字符,读n个
8、fpust(字符串,文件指针) 写入一串字符
9、fprintf(文件指针,"格式占位符...",变量...); 格式化写入文件
10、fscanf(文件指针,“格式占位符...",变量...); 格式化读取
以二进制方式读写数据
11、fread(用来保存的字符数组,数据类型的大小,数据的个数,文件指针);从文件中获取格式化的
数据
12、fwrite(需要写进去字符数组, 数据类型的大小,数据的个数, 文件指针);向文件中写入数据
13、fseek(文件指针,偏移量,起始点); 移动文件指针
偏移量为正数往后移动,负数往前移动
起始点用0、1、2代替
0(SEEK_SET)代表文件开始位置
1(SEEK_CUR)代表当前位置
2(SEEK_END )代表文件末尾位置
14、ftell(文件指针) 获取文件指针的偏移量
15、feof(文件指针) 判断文件指针是否读到末尾,读到了末尾返回真,反之假
备注:进行文件操作的时候,记得文件怎么写入的就怎么读出来,读写最好不要同时进行,注意你的操作和打
开方式
在 main.c ( 项目源文件 ) 同文件夹内 创建tese1.txt文件
在文件内键入内容:例如: “IAmMuShan”
*此处不建议输入中文 fgetc() 单个字符读写读取 1 byte ,汉字一个字符一般 2 byte 无法正常读取
本人代码新人,此处引文 : https://bbs.csdn.net/topics/390325904
关键词: fgetc(获取单个字符) putchar (释放单个字符)
void function1() {
// 1 定义变量: 文件指针
FILE* pfile = NULL;
char ch = 0;
// 2 打开文件(文件指针指向文件地址) fopen参数: 文件路径,打开方式
pfile = fopen("text1.txt", "r"); // r 为只读 此处如果文件不与代码源文件同路径则填写路径
// 3 读取(文件 ==> 程序)
// 获取一个字符 fgetc参数: 文件
ch = fgetc(pfile);
// 4 在控制台输出读取字符
putchar(ch);
printf("\nch = %c\n", ch); // 结果 : i
// 5 继续向后读取
putchar(fgetc(pfile));
printf("\n%c\n",fgetc(pfile)); // 结果 : a
// ==> 只需要调用方法 会自动向后读取
// 6 关闭文件(取消文件指针地址指向)
fclose(pfile);
pfile = NULL;
// 7 重新打开文件
pfile = fopen("text1.txt", "w"); //以写的方式打开文件;
// 8 将单个字符写入到文件(程序 ==> 文件)
fputc('X',pfile);
// ==> 会清除原来的数据 重新写入
fputc('Y',pfile);
// ==> 第一次写入到关闭之前 会自动依次写入
// 9 关闭文件
fclose(pfile);
pfile = NULL;
}
在 main.c ( 项目源文件 ) 同文件夹内 创建tese2.txt文件
在文件内键入内容:例如: “ILoveYou”
*此处虽然理论如果选择4个长度就能出来2个汉字的样子,依旧不建议用中文,根据编译器不同,可能出现各种乱码
关键词: fgets(获取字符串) fputs(释放字符串)
void function2() {
FILE * pfile = NULL;
char str[20] = {
}; //初始化字符串数组
pfile = fopen("text2.txt","r"); //只读方式打开文件
// 字符串读取函数(文件 ==> 程序)
// 参数:存储目标,长度(byte),资源文件
fgets(str , 5 , pfile);
puts(str);
printf("%s\n",str);
// ==> 此处只会出现4个字符 因为'\0'占据一个位置(\0为字符串结束的标志)
fclose(pfile);
pfile = NULL;
pfile = fopen("text2.txt", "a"); // a:追加
char str1[10] = "hello";
// 字符串输出函数(程序==>文件)
// 参数:资源,文件
fputs(str1, pfile);
fclose(pfile);
pfile = NULL;
}
在 main.c ( 项目源文件 ) 同文件夹内 创建tese3.txt文件
特点: 格式化顾名思意会在读写时清空初始内容
关键词: fscanf(格式化输入) fprintf(格式化输出)
// 三 格式化读写
void function3()
{
FILE* pfile;
int num0 = 100, num1 = 0;
float f0 = 1.2f, f1 = 0.0f;
char str0[10] = "123abc#", str1[10] = {
};
pfile = fopen("text3.txt", "w"); //此处如果文件未创建或找不到文件名会在路径内自动创建
// 程序==>文件
// 参数: 文件,格式,obj
fprintf(pfile, "%d,%f,%s", num0, f0, str0);
fclose(pfile);
pfile = NULL;
pfile = fopen("text3.txt", "r"); //此处如果文件未创建或找不到文件名 那计算机就懵逼了哈哈哈
// 文件==>程序
fscanf(pfile, "%d,%f,%s", &num1, &f1, &str1);
printf("%d , %f , %s\n", num1, f1, str1); //结果:100 , 1.200000 , 123abc#
fclose(pfile);
pfile = NULL;
}
关键词: fwrite(用于二进制写入) fread(用于二进制读取)
// 四 二进制形式读写
void function4()
{
FILE* pfile = NULL;
int arr0[10] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int arr1[10] = {
};
pfile = fopen("text4.txt", "wb"); // "wb"为二进制形式写入
fwrite(arr0, sizeof(int), 10, pfile);
fclose(pfile);
pfile = NULL;
pfile = fopen("text4.txt", "rb"); // "rb"为二进制形式读取
fread(arr1, sizeof(int), 10, pfile);
for (size_t i = 0; i < 10; i++)
{
printf("%d ", arr1[i]); // 结果: 0 1 2 3 4 5 6 7 8 9
}
fclose(pfile);
pfile = NULL;
}
由于是二进制读写 text4.txt 打开无法查看内容
通过fseek(偏移函数)改变读写位置
关键词: fseek_偏移函数
用法: fseek(文件指针,偏移量(以字节为单位),初始位置)
初始位置预处理常量:
SEEK_CUR 1 当前位置
SEEK_END 2 文件末尾
SEEK_SET 0 文件开头
void function5()
{
FILE* pfile;
char str[100] = {
};
if ((pfile = fopen("text5.txt", "r")) != NULL)
{
printf("文件打开成功!\n");
}
else
{
printf("文件打开失败!\n");
}
// 正常读取
putchar(fgetc(pfile));
putchar('\n');
/*
C 库函数 int fseek(FILE *stream, long int offset, int whence)
设置流 stream 的文件位置为给定的偏移 offset,
参数 offset 意味着从给定的 whence 位置查找的字节数。
参数:
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
offset -- 这是相对 whence 的偏移量,以字节为单位。
whence -- 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
SEEK_SET 文件的开头
SEEK_CUR 文件指针的当前位置
SEEK_END 文件的末尾
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
返回值:
如果成功,则该函数返回零,否则返回非零值。
*/
fseek(pfile, 2, SEEK_END); //使文件指针指向指定位置
fgets(str, 6, pfile);
/*
C 库函数 int ferror(FILE *stream) 测试给定流 stream 的错误标识符。
参数:
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值:
如果设置了与流关联的错误标识符,该函数返回一个非零值,否则返回一个零值。
*/
if (ferror(pfile))
{
printf("文件读取失败!\n");
}
else
{
printf("文件读取成功!\n");
}
// 打印读取的内容
puts(str);
/*
描述
C 库函数 void clearerr(FILE *stream) 清除给定流 stream 的文件结束和错误标识符。
参数
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值
这不会失败,且不会设置外部变量 errno,
但是如果它检测到它的参数不是一个有效的流,则返回 -1,并设置 errno 为 EBADF。
*/
clearerr(pfile); //清除读取/写入/ferror函数报错后出现错误的错误标志
/*
描述
C 库函数 void rewind(FILE *stream) 设置文件位置为给定流 stream 的文件的开头。
参数
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值
该函数不返回任何值。
*/
rewind(pfile);//强制使文件指针指向文件开头
/*
描述
C 库函数 int feof(FILE *stream) 测试给定流 stream 的文件结束标识符。
参数
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值
当设置了与流关联的文件结束标识符时,该函数返回一个非零值,否则返回零。
*/
while (!feof(pfile)) //feof函数判断是否读到文件末尾
{
putchar(fgetc(pfile));
}
putchar('\n');
if (fclose(pfile) == EOF)
{
printf("文件关闭失败!\n");
}
else
{
printf("文件关闭成功!\n");
}
}
完整代码:
#include
void function1(); //一. 单个字符读写
void function2(); //二. 字符串的读写
int main() {
printf("function1:\n");
function1();
printf("\nfunction2:\n");
function2();
printf("\nfunction3:\n");
function3();
printf("\nfunction4:\n");
function4();
printf("\nfunction5:\n");
function5();
}
void function1() {
// 1 定义变量: 文件指针
FILE* pfile = NULL;
char ch = 0;
// 2 打开文件(文件指针指向文件地址) fopen参数: 文件路径,打开方式
pfile = fopen("text1.txt", "r"); // r 为只读 此处如果文件不与代码源文件同路径则填写路径
// 3 读取(文件 ==> 程序)
// 获取一个字符 fgetc参数: 文件
ch = fgetc(pfile);
// 4 在控制台输出读取字符
putchar(ch);
printf("\nch = %c\n", ch); // 结果 : i
// 5 继续向后读取
putchar(fgetc(pfile));
printf("\n%c\n",fgetc(pfile)); // 结果 : a
// ==> 只需要调用方法 会自动向后读取
// 6 关闭文件(取消文件指针地址指向)
fclose(pfile);
pfile = NULL;
// 7 重新打开文件
pfile = fopen("text1.txt", "w"); //以写的方式打开文件;
// 8 将单个字符写入到文件(程序 ==> 文件)
fputc('X',pfile);
// ==> 会清除原来的数据 重新写入
fputc('Y',pfile);
// ==> 第一次写入到关闭之前 会自动依次写入
// 9 关闭文件
fclose(pfile);
pfile = NULL;
}
void function2() {
FILE * pfile = NULL;
char str[20] = {
}; //初始化字符串数组
pfile = fopen("text2.txt","r"); //只读方式打开文件
// 字符串读取函数(文件 ==> 程序)
// 参数:存储目标,长度(byte),资源文件
fgets(str , 5 , pfile);
puts(str);
printf("%s\n",str);
// ==> 此处只会出现4个字符 因为'\0'占据一个位置(\0为字符串结束的标志)
fclose(pfile);
pfile = NULL;
pfile = fopen("text2.txt", "a"); // a:追加
char str1[10] = "hello";
// 字符串输出函数(程序==>文件)
// 参数:资源,文件
fputs(str1, pfile);
fclose(pfile);
pfile = NULL;
}
// 三 格式化读写
void function3()
{
FILE* pfile;
int num0 = 100, num1 = 0;
float f0 = 1.2f, f1 = 0.0f;
char str0[10] = "123abc#", str1[10] = {
};
pfile = fopen("text3.txt", "w");
// 程序==>文件
// 参数: 文件,格式,obj
fprintf(pfile, "%d,%f,%s", num0, f0, str0);
fclose(pfile);
pfile = NULL;
pfile = fopen("text3.txt", "r");
// 文件==>程序
fscanf(pfile, "%d,%f,%s", &num1, &f1, &str1);
printf("%d , %f , %s\n", num1, f1, str1);
fclose(pfile);
pfile = NULL;
}
// 四 二进制形式读写
void function4()
{
FILE* pfile = NULL;
int arr0[10] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int arr1[10] = {
};
pfile = fopen("text4.txt", "wb");
fwrite(arr0, sizeof(int), 10, pfile);
fclose(pfile);
pfile = NULL;
pfile = fopen("text4.txt", "rb");
fread(arr1, sizeof(int), 10, pfile);
for (size_t i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
fclose(pfile);
pfile = NULL;
}
// 指定位置读写
void function5()
{
FILE* pfile;
char str[100] = {
};
if ((pfile = fopen("text5.txt", "r")) != NULL)
{
printf("文件打开成功!\n");
}
else
{
printf("文件打开失败!\n");
}
// 正常读取
putchar(fgetc(pfile));
putchar('\n');
/*
C 库函数 int fseek(FILE *stream, long int offset, int whence)
设置流 stream 的文件位置为给定的偏移 offset,
参数 offset 意味着从给定的 whence 位置查找的字节数。
参数:
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
offset -- 这是相对 whence 的偏移量,以字节为单位。
whence -- 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
SEEK_SET 文件的开头
SEEK_CUR 文件指针的当前位置
SEEK_END 文件的末尾
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
返回值:
如果成功,则该函数返回零,否则返回非零值。
*/
fseek(pfile, 2, SEEK_END); //使文件指针指向指定位置
fgets(str, 6, pfile);
/*
C 库函数 int ferror(FILE *stream) 测试给定流 stream 的错误标识符。
参数:
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值:
如果设置了与流关联的错误标识符,该函数返回一个非零值,否则返回一个零值。
*/
if (ferror(pfile))
{
printf("文件读取失败!\n");
}
else
{
printf("文件读取成功!\n");
}
// 打印读取的内容
puts(str);
/*
描述
C 库函数 void clearerr(FILE *stream) 清除给定流 stream 的文件结束和错误标识符。
参数
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值
这不会失败,且不会设置外部变量 errno,
但是如果它检测到它的参数不是一个有效的流,则返回 -1,并设置 errno 为 EBADF。
*/
clearerr(pfile); //清除读取/写入/ferror函数报错后出现错误的错误标志
/*
描述
C 库函数 void rewind(FILE *stream) 设置文件位置为给定流 stream 的文件的开头。
参数
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值
该函数不返回任何值。
*/
rewind(pfile);//强制使文件指针指向文件开头
/*
描述
C 库函数 int feof(FILE *stream) 测试给定流 stream 的文件结束标识符。
参数
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
返回值
当设置了与流关联的文件结束标识符时,该函数返回一个非零值,否则返回零。
*/
while (!feof(pfile)) //feof函数判断是否读到文件末尾
{
putchar(fgetc(pfile));
}
putchar('\n');
if (fclose(pfile) == EOF)
{
printf("文件关闭失败!\n");
}
else
{
printf("文件关闭成功!\n");
}
}