




免费预览已结束,剩余51页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
高级语言程序设计(一) (c programming),第六讲:高级程序设计,本章目标,掌握文件结束判断方法; 掌握文件格式化输入/输出方法; 了解文件块输入/输出方法; 了解文件读写位置操作。 熟悉预处理语句; 了解变量作用域; 了解位运算;,文件输入/输出(复习),文件输入/输出过程,打开文件,首先在程序文件的头部应有如下语句: #include ,stream (流,读写通道),程序结束前应该关闭文件,!,程序,文件,打开文件(复习),例如:以只读方式打开一个文件“hello.c”。 fp = fopen(“hello.c”, “r”); 例如:以写方式打开一个文件“output.dat”,该将文件位于c:盘根目录下。 fp = fopen(“c:output.dat”, “w”);,读写文件(复习),字符输入函数: int fgetc (file * fp ); 从fp所指向的文件中读取一个字符并返回。若文件结束或调用失败,返回eof 字符输出函数: int fputc ( int ch, file * fp ); 将字符ch写入fp所指向的文件。若成功,则返回写入的字符;若失败,返回eof,关闭文件(复习),关闭文件函数: int fclose (file* fp ); 关闭fp文件指针所指向的文件,并释放fp文件指针。若成功关闭,返回0,否则返回eof,例:将文件in.doc拷贝至新文件out.doc中。,#include void main() char ch; file * in, * out; if(in=fopen(“in.doc“,“r“)=null) printf(“cant open in.doc!“); return; if(out=fopen(“out.doc“,“w“)=null) printf(“cant open out.doc!“); return; while( (ch = fgetc(in) !=eof ) fputc(ch,out); fclose(in); fclose(out); ,结果:不能正确读取in.doc!,?,打开文件(续)*,文本文件与二进制文件 例:整数 1949 (0x079d), 使用printf %d输出,c语言支持文本形式和二进制形式的文件操作,无论那种形式,都把文件看作一个字节的序列,对文件的存取是以字节为单位进行的。,1 9 4 9,文本文件便于显示,二进制文件节省存储空间,处理速度快,一般用于保存大量数据。,文件,打开文件(续) *,以二进制流打开文件的方式包括: “rb”: 表示读; “wb”: 表示写; “ab”: 表示添加; “rb+”: 表示读写已有文件; “wb+”: 表示读写新文件; “ab+” : 表示读及添加;,文件结束判断,在二进制文件中不设eof标志(因为-1为合法数据),文件结束测试函数: feof ( fp ); 若最近一次读取fp所指向的文件时,读取了文件尾部,则返回非0值,否则返回0,文件结束判断(续),test.txt: abc,int count = 0; int ch; while(!feof(fp) fgetc(ch,fp); count+ +; ,count值:,1,ch值:,a,2,b,3,c,尾部:最后一个字节后,4,-1,#include void main() char ch; file * in, * out; if(in=fopen(“in.doc“,“rb“)=null) printf(“cant open in.doc!“); exit(1); if(out=fopen(“out.doc“,“wb“)=null) printf(“cant open out.doc!“); exit(1); ch = fgetc(in); while( !feof(in) ) fputc(ch,out); ch = fgetc(in); fclose(in); fclose(out); ,这种文件读写方法可用于任何类型的文件,包括文本文件,能否改成: while (!feof(in) ch=fgetc(in); fputc(ch,out); ,问题6.1,问题:unix下有一个命令cat,其用法为: cat x.c y.c z.c 其在标准输出(屏幕)上依次显示每个文件内容。如果没有文件名,则显示标准输入中的内容。它类似于windows的command环境下的type命令。,问题6.1:算法设计,主要算法如下: if 没有命令行参数 从标准输入中读取内容并显示到屏幕上; else while 还有文件未读取 打开文件; 从文件输入中读取内容并显示到屏幕上; 关闭文件;,设计一个函数: void filecopy(file *fp) 从文件或标准输入中输入并显示到屏幕上。,问题6.1:代码实现,#include void filecopy(file *fp); int main( int argc, char *argv ) file *fp; int i=1; if( argc = = 1) filecopy(stdin); else while( iargc ) if( fp = fopen(argvi+, “r”) = = null) printf(“cat: cant open %sn”, *argv); return 1; else filecopy(fp); fclose(fp); return 0; ,void filecopy( file *fp) int c; while(c = fgetc(fp) != eof) fputc(c, stdout); ,错误处理及出口,出错时可调用exit(1), 非正常出口。 一般正常退出可调用exit(0)。 函数exit为每个打开的文件调用fclose,清除缓冲区,再通过系统调用命令_exit退出。,错误处理及出口(续),对上例cat程序可作如下修改。 main( int argc, char *argv ) file *fp; if( argc = = 1) filecopy(stdin); else while(-argc 0) if( fp = fopen(*+argv, “r”) = = null) printf(“cat: cant open %sn”, *argv); return 1; else filecopy(fp); fclose(fp); return 0 ,fprintf(stderr, “cat: cant open %sn”, *argv); exit(1);,exit(0);,exit函数通常用于当存在多层函数调用时退出程序。,行输入/输出,char *fgets(char *s, int n, file *fp) 从fp上最多读入n-1个字符,放入s 字符数组中。返回s或null。 int fputs( char *s, file *fp) 把字符串s(不一定含n)写入文件fp中。返回非负数或eof。 fgets正常读入换行字符(与gets不同); fputs不在输出后自动加换行字符(与puts不同); fgets能设置字符的最大个数,因此,当无法确定所读入的数据行有多长时,最好使用fgets,而不用gets。如: fgets(buf, 81, stdin);,while ( fgets( s, 81, fp ) != null ) ,文件格式化输入/输出,文件格式化输入/输出函数: fscanf(fp, format, ) fprintf(fp, format, ) 比scanf、printf函数分别多了一个文件指针参数。,例如:从文件student.in中读入最多不超过50个学生的学生信息,分别以姓名顺序(从低到高)将学生信息输出到文件student.out中。,4 1 lisan 22 45 wang 23 54 liu 20 110 zhang 19,返回成功读入的 数据个数,若到达 文件末尾或转换 出错,则返回eof,文件格式化输入/输出(程序实例),int main() struct student stu50; int number, i; file *in,*out; in=fopen(“studentin.in“,“r“); out=fopen(“studentout.out“,“w“); fscanf(in,“%d“, ,struct student int id; char name7; int age; ;,文件格式化输入/输出,举例:读入文件中的单词(假如单词数不超过100,每个单词长度不超过100个字符) 问题分析: 1、如何判断是否读完? 利用fscanf的返回值,若大于0,则未读 完,否则,读完或读入错误。 2、如何保存读入的单词? char words100101; char *pwords100;,文件,读入单词:,char words100101; int i=0; while ( fscanf ( in, “%s“, wordsi ) 0 ) i+;,char * pwords100, temp101; int i=0; while ( fscanf( in, “%s“, temp ) 0 ) pwordsi = ( char * ) malloc( strlen(temp)+1 ); strcpy ( pwordsi, temp ); i+; ,读写文件(续),其它文件读写常用函数: getc( fp ), putc(c, fp) 而getc, putc和fgetc,fputc的区别是fgetc和fputc是函数,而getc和putc是宏定义。,块输入/输出,size_t fwrite(const void *ptr, size_t size, size_t nobj, fle *fp) 从指针ptr所指的对象中,向文件fp中写入大小为size的nobj个对象。其返回值为实际写入的对象数。 size_t fread(void *ptr, size_t size, size_t nobj, file *fp) 从文件fp中读入大小为size的nobj个对象,放入指针ptr所指的对象中。其返回值为实际读入的对象数。 通常它们被用来输入或输出象结构这样的成块数据。如: fwrite(buf, sizeof(struct student), n, fp); fread(buf, sizeof(struct student), n, fp);,块输入/输出(续),注意: 块输入/输出又称直接输入/输出,不进行数据格式的转换 ,因此属于二进制流形式的输入/输出操作。 用fwrite函数写入数据的文件,其内容一般无法用普通的编辑器查看或修改。 一般用于保存数据,为了以后重新读取使用。 fwrite和fread函数一般配对使用: 用fwrite写入的数据一般通过fread函数读取; 用fread读取的数据也一般是用fwrite函数写入的。,文件读写位置与随机输入/输出,每个正在读写的文件都有一个当前文件读写位置。 如何得到当前文件读写位置? long ln = ftell(fp); 返回fp所指文件的读写指针当前位置,即相对于文件开始处的位移量,单位是字节。若调用失败,返回-1。,文件读写位置与随机输入/输出(续),如何改变文件读写位置? 通常在做顺序读写时,不用关心文件读写位置。 可用下面函数来改变文件读写位置: fseek ( fp, offset, origin ); 将fp所指向文件的读写指针相对于origin移动offset个字节。若成功,返回0,否则返回非0值。,origin在stdio.h文件中有定义,可取以下值: 常量标识符 值 含义 seek_set 0 文件开始位置 seek_cur 1 文件读写指针当前位置 seek_end 2 文件结束位置,例如: fseek(fp, 0, seek_set); 将文件指针移至文件头 fseek(fp, -5, seek_end); 将文件指针移至距文件尾5字节处,文件读写位置与随机输入/输出(续),文件复位函数: void rewind ( file * fp ); 将fp所指向文件的读写指针重新定位到文件的开始。,sscanf(char * s, char *format , pointer) 从字符串s中读取数据并转换成相应数据格式的变量; 格式转换方式同scanf。 sscanf适合用来将字符数据转换成整数、浮点数或较短的字符串,它通常用以将事先读入的一行数据,依其不同的字段分开。如: char *buf = “123.456 + 595.36”; float val1, val2; char oper; sscanf(buf, “%f %c %f”, ,其它常用库函数,sprintf(char * s, char *format , arg) 把变量转换成相应格式后,保存到字符串s中; 格式转换方式同printf。 当需要把某种类型的数据转换成字符串时,sprintf就特别有用。如: char buf100, *cmd= “test”; int width = 80; double x = 5.67; sprintf(buf, “%s %d %f”, cmd, width, x); printf(“%sn”, buf);,其它常用库函数(续),其它常用库函数(续),字符类别测试和转换 #include isalpha(c) c为字母,则为非0;否则结果为0 isupper(c) islower(c) isdigit(c) isspace(c) c为空白、换行、制表符,则为非0;否则结果为0 toupper(c) 将c转换成大写字母 tolower(c) 将c转换成小写字母,#define isupper(c ) (c =a & c=z)?1:0,其它常用库函数(续),ungetc(c, fp) #include 把字符c退回到文件fp 中。 系统调用 #include system(s) 执行字符串s中的命令。如system(“date”);显示日期和时间。 存贮管理 #include void *malloc(size_t size); void *calloc(size_t nobj, size_t n); void free(void *p);,其它常用库函数(续),串操作 #include char *strcpy(char *s1, char *s2); char *strcat(char *s1, char *s2); int strcmp(char *s, char *t); int strlen(char *s); char *strchr(char *s, char c); char *strstr(char *s1, char *s2); 转换函数 #include double atof(const char *s); int atoi(const char *s); long atol(const char *s);,预处理程序,预处理关键字: #define #undef #include #if #ifdef #ifndef #else #endif #line,预处理程序:include,包含文件(include) 格式: #include “文件名” 一般头文件 #inlcude 系统头文件 编译程序以该文件名的内容来替换该控制行,通常在每个源文件开头出现这样的行,是为了包含公共的#define和外部变量的说明以及函数原型。,预处理程序:include(续),使用#include可把其它文件(往往是.h文件)的内容包含进来,#include还允许嵌套使用,如:,预处理程序:include(续),使用#include的优点 可以把所有公共的、需要给程序各个函数共享的外部变量说明、函数原型和宏定义、类型定义等都放在某一文件上(通常以.h为文件后缀)。其它文件的开头只须用一条#include “该.h”文件的语句,就可以省去重写这些说明、定义的麻烦,而且程序结构更为清晰。如: #include #include #include “local.h”,预处理程序:if,条件编译(if) c语言预处理程序提供了根据条件对程序段进行有选择地编译的能力,而这些控制行本身不参加编译。 条件编译形式如下: #if 常量表达式 #ifdef 标识符 #ifndef 标识符,预处理程序:if(续)*,如: #if 常量表达式 程序段1 - 常量表达式为真时编译 #else 程序段2 - 常量表达式为假时编译 #endif 又如: #ifdef spe_ver - spe_ver已定义时编译 #else - spe_ver未定义时编译 #endif,预处理程序:if(续),我们经常可在一些头文件中见到下面语句: #ifndef first #define first #endif 可用它们来避免该头文件被重复包含。,变量作用域,变量作用域:变量的使用范围; 在同一个作用域内,不允许定义同名变量; 在不同作用域内,允许定义同名变量。如果同名变量作用域重叠,则内层变量将屏蔽外层变量;,变量作用域,变量作用域(续),例: #include int i = 0; main( ) int i = 1; printf(“i=%d, ”, i); int i = 2; printf(“i=%d, ”, i); i += 1; printf(“i=%d, ”, i); printf(“i=%d, ”, i); printf(“i=%dn ”, i); ,结果:? i=1, i=2, i=3, i=3, i=1,注意:在程序中出现作用域重叠的同名变量不是一个好的程序设计风格。,静态变量(static)*, 内部静态变量 在局部变量前加上“static”关键字就成为内部静态变量。 内部静态变量仍是局部变量,其作用域仍在定义它的函数内。但该变量采用静态存贮分配(由编译程序在编译时分配,而一般的自动变量和函数形参均采用动态存贮分配,即在运行时分配空间),当函数执行完,返回调用点时,该变量并不撤消,其值将继续保留,若下次再进入该函数时,其值仍存在。 外部静态变量 在函数外部定义的变量前加上“static”关键字便成了外部静态变量。 外部静态变量的作用域为定义它的文件,即成为该文件的的“私有”(private)变量,其它文件上的函数一律不得直接进行访问,除非通过它所在文件上的各种函数来对它进行操作,这可实现数据隐藏。(在c+中提供进一步的数据隐藏。),静态变量(static)(续)*,例:下列程序打印出什么结果。 #include int f(int i); main() int i; for(i=0; i 5; i+) printf(“%d “,f(i); int f(int i) static int k = 1; k += i; return (k); ,结果: 1 2 4 7 11,变量初始化,外部和静态变量由编译程序给予隐含的初值0。 程序员可在变量定义时对它进行初始化(不是赋值表达式)。 如: binary(int x, int y, int n) int low = 0; int high = n 1; ,变量初始化(续),自动变量的初始化每进入该函数时便初始化一次。 外部或静态变量的初始化仅(在编译时)进行一次。 自动变量或寄存器变量只能显式初始化,否则,自动变量和寄存器变量有不确定的值。 *外部数据的说明,如果带有初始化项,即当成一个定义。,枚举类型(enum),枚举型变量的取值仅限于规定的一组值之一。 定义形式: enum 枚举名 值表 ; 例: enum color red, green, yellow, white, black ; /* 枚举值是标识符 */ 枚举变量说明 enum color chair; enum color suite10;,枚举类型(续),在表达式中使用枚举变量 chair = red; suite5 = yellow; if( chair = = green ) 注意:对枚举变量的赋值并不是将标识符字符串传给它,而是把该标识符所对应的各值表中常数值赋与变量。c语言编译程序把值表中的标识符视为从0开始的连续整数。另外,枚举类型变量的作用范围与一般变量的定义相同。 如: enum color red, green, yellow = 5, white, black ; 则: red=0, green=1, yellow=5, white=6, black=7,枚举类型(续),枚举类型用途: 枚举类型通常
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年3D打印的3D打印应用
- 2025大数据分析在体育训练中的应用
- 交通银行2025扬州市秋招群面案例总结模板
- 2025养老金融行业市场分析与发展
- 2025行业绿色技术发展前景
- 工商银行2025上海市秋招半结构化面试题库及参考答案
- 中国银行2025金昌市秋招笔试英语题专练及答案
- 邮储银行2025雅安市数据分析师笔试题及答案
- 技术合同技术转让合同(3)2篇
- 中国银行2025丹东市秋招群面案例总结模板
- 2025年银行内部审计部门财务审计员竞聘考试指南
- 流水别墅案例分析
- 录入与排版教学计划
- 2023免拆底模钢筋桁架楼承板图集
- 云计算技术基础应用教程(HCIA-Cloud)PPT完整全套教学课件
- 呼吸衰竭小讲课课件
- 成人学士学位英语1000个高频必考词汇汇总
- GB/T 5271.29-2006信息技术词汇第29部分:人工智能语音识别与合成
- 全屋定制家居橱柜衣柜整装安装服务规范
- 沥青及沥青混合料试验作业指导书
- 义务教育阶段学生艺术素质测评指标体系小学音乐
评论
0/150
提交评论