您的位置:首页 > 编程语言 > C语言/C++

黑马程序员------C语言基础 预处理指令、文件操作及其他

2015-07-25 22:41 495 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
预处理指令、文件操作及其他

以"#"号开头的预处理指令,如命令#include,宏定义命令#define等。在源程序中这么命令都放在函数之外,而且都放在源文件前面,他们称为预处理部分

所谓预处理是指在进行编译的第一遍(词法扫描和语法分析)之前的工作。

x 语言多种预处理指令功能:宏定义、文件包含、条件编译

.o .out

源程序->预处理(宏替换)-> 编译 -> 链接-> 执行程序

一、预处理指令

1、宏定义

宏:在c语言中我们自定义的标示符,习惯大写

#include 宏名 宏字符串 (可以是常量、变量、表达式)

注意:预处理指令,经常写在函数之前

宏替换:源程序在编译之前,由预处理程序对我们写的源代码进行处理:会把源代码中所出现 宏名 的地方一律使用 宏的字符串 去替换

宏使用的注意事项:

1.宏是有作用域的 #undef 宏名 可以取消宏定义

#include R 4

int a= R

#define R M 这里取消宏定义,下面的代码用不了宏了

2.在字符串中出现的宏名不会被替换

3.宏定义可以嵌套使用

#define R 4

#define PI 3.14

#define AREA PI*R*R //嵌套定义

4,使用宏起别名

#include INT1 int

这样就可以 这么定义整型

INT1 a=10;

5.有参数宏和无参数宏

无参数宏 #include M 10

有参数宏 #define SUM(a) a+a

有参数宏的使用注意事项:

宏的形参之间可以出现空格 ,但是宏名和形参之间不能空格

有参数宏 宏的参数最好用括号括起来

应用使用有参宏求最大值

#include <stdio.h>

//定义一个有参宏 求两个数的最大值

#define MAX(a,b) a>b?a:b

int main(int argc, const char * argv[]) {

// 调用宏

int c =MAX(3, 4);

printf("最大值是%d",c);

return 0;

}

6 typedef 和#include 的区别

当 #include INT1 int

typedef int INT2;

这里 INT1 a,b a,b都是定义的整型变量

INT2 a,b 也一样是整型变量

定义指针时

#include INT3 int*

typedef int* INT4 ;

INT1 f1,f2 =NULL; 这里f1 是zhiz 而f2只是个整型变量 说明宏的定义知识单纯的文本复制的替换

INT4 f1,f2 = NULL; 这里 f1,f2 都是指针。

2.条件编译指令

1. #if -#elseif

条件编译 :

发生在预处理阶段 ,在编译之前做的事情

核心:根据条件编译指定的代码

条件不同,编译的部分也不同,生成的目标文件(.o)大小也不一样

传统方式

int score =76;

判断成句属于哪个成绩

if(score<60){

printf("E\n");

}else if(score<= 69){

printf("d\n");

}else if(score<= 79){

printf("c\n");

}else if(score<= 89){

printf("b\n");

}else {

printf("A\n")

}

#if score <60

printf("E\n");

#elif scoe <=69

printf("d\n");

#elif scoe <=79

printf("c\n");

#elif scoe <=89

printf("b\n");

#else

printf("a\n");

#endif

这里只选择一个符合要求的score 进行一段代码的预编译

2.#ifdef 有来判断某个宏是否定义

#include DEBUG1 1

int a=0;

#ifdef DEBUG1 DEBUG1为1是执行 a=10 ;

a=10; 否则执行 a=100;

#else

a=100;

#endif

3.使用条件编译指令调试bug

#if DEBUG1 ==1 1或0 1显示调试信息 0不显示调试信息

//显示调试信息

#define Log(format,....)printf(format,##__VA_ARGS__);

#else

#define Log(format,.......)

//不显示调试信息

#endif

二、文件操作

1。文件概念

文件; 指存储在外部介质上数据的集合,这个数据有一个名称,叫做文件名

文件的分类 从用户角度 文件分为普通文件和设备文件

从文件编码 文件分ascii码文件和二进制文件

文件操作的步骤

1)引入头文件<stdio.h>

2)定义文件指针

3)打开文件

4)文件读写

5)关闭文件

对文件读和写是最常用的文件操作,在c语言中提供了多种文件读写的函数

字符读写函数 fgetc和fputc

读写字符串函数 fgets和fputs

数据快读写函数 fread 和fwrite

格式化读写 fscanf 和fprintf

c语言文件指针

在c语言中用一个指针变量指向一个文件,这个指针称为文件指针

文件指针

FILE *指针变量表示符;

2。文件的打开和关闭函数

文件操作步骤

1)引入头文件 stdio.h

2)建立文件指针 FILE *fp =NULL;

3)打开文件 fopen(文件名,操作方式);

如果文件打开成功返回文件收地址,失败返回NULL

4)操作文件

5)关闭文件 fclose(文件指针);

#include <stdio.h>
int main(int argc, const char * argv[]) {
//定义文件指针
FILE *fp =NULL;
//打开文件  是文件操作方式
fp =fopen("a.txt", "r");
//fopen成功,返回的是文件首地址
//fopen失败 返回NULL
if(fp!=NULL){
//文件操作
printf("文件打开成功\n");
}else{

//给用户提示
printf("文件打开失败,请任意键退出\n");
//按任意键推出
getchar();//要求从键盘接受一个字符
//退出
exit(1);//非正常退出

}
//文件关闭

fclose(fp);

return 0;
}

3文件使用的方式及注意事项

文件使用方式

4字符读写函数 fgetc和putc

字符读写函数是以字符(字节)为单位的读写函数。每次可以从文件读出或向文件写入一个字符

fputc() 写入一个字符到文件中

假设把 ch写到 fputc1.txt 文件中

char ch ='x''

#include <stdio.h>
void test(){

char ch ='x';
//打开文件 打开fputc1.txt 以w方式(写,如果文件不存在可创建)
FILE *fp=fopen("fputc1.txt", "w");
//判断文件是否打开成功
if (fp != NULL) {
//将ch 要写入的字符  文件指针
//写到fput1.txt文件中
fputc(ch,fp);
printf("写入成功\n");
}
//关闭文件
fclose(fp);

}

int main(int argc, const char * argv[]) {
FILE *fp=fopen("fputc1.txt", "r");
//判断文件是否打开成功
c = fgetc(fp);

if (fp != NULL) {
//字符文件要读取到的位置 c 文件指针
//写到fput1.txt文件中
printf("%c\n",c);
printf("文件打开成功\n");
}
//关闭文件
fclose(fp);
return 0;

}

使用 fgetc 和fputc 读取和写入字符串
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
//定义文件指针,打开文件 futcString.txt 以w写入
FILE *fp=fopen("fputcString.txt","r");
if(fp!=NULL){
//        char ch[]="i love china";
//        for(int i=0;i <strlen(ch);i++){
//            fputc(ch[i], fp);
//            printf("文件写入成功]\n");
//        }
//
char s =fgetc(fp);
//EOF是文件的末尾的标志
//s ==EOF 可以理解为,已经读取到文件的最后了
while (s!=EOF) {
putchar(s);//输出字符
s = fgetc(fp);//又从文件中读取下一个字符。这里fgetc 会自动转换指针指向下一个字符。
}

}
fclose(fp);
return 0;
}

保存键盘输入的字符串
#include <stdio.h>
int main(int argc, const char * argv[]) {
FILE *fp =fopen("string1.txt","w+");
if (fp!=NULL) {
printf("请输入一个字符串\n");
char ch;
ch = getchar();
<pre class="csharp" name="code">5.字符串读写函数 fgets 和fputs
#include <stdio.h>

int main(int argc, const char * argv[]) {
//把字符串写入到文件中去
char str[]="welcome to yilake";
FILE *fp = fopen("fputsstring.txt", "w+");
if (fp!=NULL) {
int count =0;
// 写入字符串到文件中 ,count 返回读取的字符数
count = fputs(str,fp );
printf("写入成功,本次写入%d个字节]\n",count);

rewind(fp);
char str1[20];
//从文件中读取字符到字符数组str1中
//  数组名   长度     文件指针

fgets(str1, sizeof(str1),fp);
// fgets读取的时候,当文件读取完会自动的给字符后面加'\0'
//fgets读取的时候,遇到\n或者EOF ,读取完毕
printf("输入的字符串是%s",str1);
}
//关闭文件指针
fclose(fp);
return 0;
}


int count = 0; while (ch!='\n') { count++; fputc(ch, fp);//把字符保存到文件中 ch = getchar();//获取下一个字符串 } printf("本次一共写入了%d个字符\n",count); printf("1----------\n"); rewind(fp);//作用是把问价指针,重新指向文件首地址 int k = 0; //从文件中读取一个字符 ch = fgetc(fp); while (ch!=EOF) { k++; //显示到控制台
putchar(ch); //读取一个字符 ch =fgetc(fp); } printf("本次共输出了%d个字符\n",k); } fclose(fp); //关闭读取文件 return 0; }

6.数据快的读写函数fread 和fwrite

一般形式fread(buffer,size,count,fp);

fwrite(buffer,size,count,fp);

buffer时指针用来存放数据输入的首地址 表示存放数据输出的首地址

size 表示数据块字节数

count 表示要读写的数据块块数

fp 表示文件指针

#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[]) {
//fwrite 写一个数据块
//先写一个字符串
FILE *fp =fopen("fwrite.txt", "w+");
if (fp!=NULL) {
//        写文件
char *str ="helloworld!";
//fwrite(地址,块大小,数据,文件指针);
fwrite(str,strlen(str),1,fp);
printf("文件写入成功\n");
rewind(fp);
char str1[12];
//读出一个到字符数组str1中
fread(str1, sizeof(str1), 1, fp);
printf("%s",str1);
}
fclose(fp);
return 0;
}
应用读写结构体
#include <stdio.h>
struct Student{
char name[21];
int age;
float score;

};
int main(int argc, const char * argv[]) {
struct Student stu[2]={{"李白",18,88.88f},{"杜甫",23,99.99f}};
FILE *fp =fopen("studentScore.data","wb+");
if (fp!=NULL) {
for (int i=0; i<2; i++) {
//从文件中读取一个元素(32)到stu中去
//每次都写入一个元素
fwrite(&stu[i], sizeof(struct Student), 1,fp);
}

printf("写入成功\n");
printf("————————————————— ii\n");
rewind(fp);
struct Student stu1[2];
//从文件循环读取
for (int i=0; i<2; i++) {
//从文件中读取一个元素(32)到stu中去
fread(&stu1[i], sizeof(struct Student), 1,fp);
}
//查看读取数据
for (int i = 0; i<2; i++) {
printf("姓名%s 年龄%d 成绩%.2f\n",stu1[i].name,stu1[i].age,stu1[i].score);
}
}

fclose(fp);
return 0;
}


7.格式化读写函数 fscanf和 fprintf

两个函数调用的格式

fscanf(文件指针,格式字符串,输入列表);

fprintf(文件zhiz,格式化字符串,输出列表);

列如要求 把数据照这个样格式

0#1;

1#2;

2#3;

#include <stdio.h>

int main(int argc, const char * argv[]) {

FILE *fp =fopen("fprintf.txt", "w+");
if (fp!=NULL) {
int a= 3,b=4;
fprintf(fp,"%d#%d;",a,b );
printf("写入成功\n");

rewind(fp);//指针回到文件首地址
int m=0,n=0;
//从文件中读取数据到变量中
fscanf(fp, "%d#%d;",&m,&n);
printf("%d,%d",m,n);

}
fclose(fp);
return 0;
}

8.读取和写入一个二维数组

#include <stdio.h>
int main(int argc, const char * argv[]) {
int a[3][2]={1,2,3,4,5,6};
FILE *fp =fopen("arr.txt", "w+");
if (fp!=NULL) {
for (int i=0; i<3; i++) {
fprintf(fp, "%d,%d#", a[i][0],a[i][1]);
}
printf("写入成功\n");
rewind(fp);
int c[3][2];
for (int i=0; i < 3; i++) {
fscanf(fp, "%d,%d#",&c[i][0],&c[i][1]);
}
for (int i=0; i<3; i++) {
for (int j=0; j <2 ;j++ ) {
printf("%d\t",c[i][j]);
}
}

}
fclose(fp);
return 0;
}


9文件的随机读写实现

fseek(文件zhiz,位移量 ,起始点);

位移量 表示移动的字节数,要求位移量是long类型数据,要求加后缀“L”

起始点 表示从何处开始计算位移量,规定的起始点有三种,文件首,当前位置和文件尾。

文件首 SEEK_SET 0

当前位置 SEEK_CUR 1

文件末尾 SEEK_END 2

只输出第二个人的信息

#include <stdio.h>
struct  Student{
char*name;
int age;
float score;
};
int main(int argc, const char * argv[]) {
struct Student gril[3]={{"zsf",18,34.55f},{"lzl",23,88.88f},{"lzz",22,99.99f}};
FILE *fp =fopen("student.data", "w+");
if (fp!=NULL) {
for (int i =0; i<3; i++) {
fwrite(&gril[i], sizeof(struct Student), 1, fp);
}
printf("写入成功\n");

rewind(fp);
//         移动的字节数             起始点
struct Student gril1;
// 文件定位 从起始点开始移动(32个字节)
fseek(fp, sizeof(struct Student), SEEK_SET);

fread(&gril1, sizeof(struct Student),1, fp);
printf("姓名 %s 年龄%d 成绩%.2f\n",gril1.name,gril1.age,gril1.score);
}

return 0;
}

10.文件结束检函数feof

feof(fp)也就是找文件结束的标志。

读写出错函数 ferror (文件指针);

能检查文件在输入输出时读写是否出错 如果ferror返回的时0就表示没有出错,否则表示文件有错。

文件出错标志和文件结束标志函数

clearerr(文件指针) 用于清除错误标志和文件结束标志,使他们为0值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: