510 likes | 714 Views
第 2 讲 数据输入 / 输出的概念. 1. 熟练掌握常用输入输出函数: scanf 、 printf 、 getchar 、 putchar 、 gets 、 puts 等 2. 熟练掌握文件的打开和关闭 ---fopen() 和 fclose() 3. 熟练掌握文件的基本读写操作 常用函数: fscanf 、 fprintf 、 fgetc 、 fputc 、 fgets 、 fputs 等 4. 熟练掌握文件的状态检测 ----feof() 函数. 一、数据输入 / 输出的概念. 从键盘将数据输入. 将数据输出到屏幕.
E N D
第2讲 数据输入/输出的概念 1.熟练掌握常用输入输出函数:scanf、printf、getchar、putchar、gets、puts等 2.熟练掌握文件的打开和关闭---fopen()和fclose() 3.熟练掌握文件的基本读写操作 常用函数:fscanf、fprintf、fgetc、fputc、fgets、fputs等 4.熟练掌握文件的状态检测----feof()函数
一、数据输入/输出的概念 从键盘将数据输入 将数据输出到屏幕 getchar(),getch(),gets() scanf() putchar(), put() printf() 内存 从数据文件读入 RAM 将数据输出到文件 fgetc(), fgets() fscanf(), fread() fputc(), fputs() fprintf(), fwrite() 说明: (1) 数据输入/输出是相对计算机内存 (2) 数据输入/输出使用标准库函数完成 (3) 数据输入/输出标准库函数的原型声明在stdio.h头文件中
二、字符(串)键盘输入/屏幕输出 1、字符输出函数putchar() putchar 函数是字符输出函数, 其功能是在显示器上输出单个字符。 其一般形式为: putchar(字符变量); 例如: putchar('A'); 输出大写字母A putchar(x); 输出字符变量x的值 putchar(‘\n’); 换行 说明:使用本函数前必须要用文件包含命令: #include "stdio.h"
二、字符(串)键盘输入/屏幕输出 2. 字符串输出函数——puts() 字符串输出函数puts使用格式:puts (st) 其中:st可以是己定义的字符数组名,也可以是指向字符变量的指针变量。 功能:把字符数组中或指针变量所指向的字符串输出到显示器。输出从数组的第一个字符或指针所指向的字符到字符串(以‘\0’结尾)之间的所有字符。例: char c[6]="China"; puts(c); puts不需要格式控制符,输出完后且自动换行,等价于:printf("%s\n",c); char c[]=“abc\0sjd\3” ;puts(c); 输出结果为: abc
二、字符(串)键盘输入/屏幕输出 3、字符输入函数getchar( ) 函数getchar函数的功能是从键盘上输入一个字符。 其一般形式为:字符变量=getchar(); 如: #include<stdio.h> void main() { char c; printf("input a character\n"); c=getchar(); putchar(c); } 使用getchar函数还应注意几个问题:
二、字符(串)键盘输入/屏幕输出 说明: getchar函数只能接受单个字符,输入数字也按字符处理。 输入多余的字符存入到键盘的缓冲区,若有下一个getchar函数语句,直接从键盘的缓冲区读取。 #include<stdio.h> main() { char c1,c2; c1=getchar(); c2= getchar(); putchar(c1);putchar(c2); } 当程序运行后:输入ABCDEF ,输出为:
二、字符(串)键盘输入/屏幕输出 2. getch() 它与getchar()函数的区别是输入不需要回车键结束,即输入一个字符就自动结束输入。它们的调用格式为: getch(); 该函数不将读入的字符回显在显示屏幕上,利用回显和不回显的特点,它经常用于交互输入的过程中完成暂停等。 在调试程序时,也经常可在main函数最后增加一个getch();以直接观察程序的运行结果而不必每次都使用Alt+F5切换窗口 例如: #include<stdio.h> void main() { float x; printf("Enter The Number x:"); scanf("%f",&x); printf("Ente x=%f\n " ,x); ……… printf("Press any key to confinue..."); getch(); /*等待输入任一键*/ }
二、字符(串)键盘输入/屏幕输出 4. 输入字符串函数——gets()函数: 字符串输入函数gets 格式: gets (st) 功能:从标准输入设备键盘上输入一个字符串。本函数得到一个函数值,即为该字符数组的首地址。 说明:gets函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束。这是与scanf(“%s”,…)函数不同的。
二、字符(串)键盘输入/屏幕输出 例字符串的输入示例 #include "stdio.h" void main() { char st1[20],st2[20]; printf("input string:\n"); gets(st1); scanf("%s",st2); puts(st1); puts(st2); } 程序运行结果是:
三、格式输入/输出 格式输出函数printf() 一般形式为: printf(“格式控制字符串”,输出表列) d输出数据的类型 x输出项 例如:printf("%3d\n",x) %格式说明起始符 3输出数据的宽度
a=3; b=4; printf("%d %d", a , b); 输出结果: 3 4 格式说明 输出表列 输出结果: a=3 , b=4 printf("a=%d , b=%d",a , b); 普通字符 printf("a=%d b=%d",a ,b); 输出结果 : a=3 b=4 格式输出函数printf() 例如: 可见,双引号中的字符除了格式说明的字符外,其它非格式说明的普通字符按原样输出。
格式输出函数printf() 说明:格式字符串的一般形式为: % [标志][输出最小宽度][精度][长度]类型字符 其中方括号[]中的项为可选项。 1. 类型字符 用以表示输出数据的类型: C语言中输出不同数据,使用不同的类型字符, 例如:输出整型数据,使用的类型符 d,i (小写)
格式输出函数printf( ) 表示输出类型的格式字符及 意义 d, i以十进制形式输出带符号整数(正数不输出符号) o以八进制形式输出无符号整数(不输出前缀O) x, X以十六进制形式输出无符号整数(不输出前缀OX) u以十进制形式输出无符号整数 f以小数形式输出单、双精度实数 e ,E以指数形式输出单、双精度实数 g ,G以%f%e中较短的输出宽度输出单、双精度实数 c输出单个字符 s输出字符串
格式输出函数printf() 2.标志 -、+、#、空格四种, -结果左对齐,右边填空格 +输出符号(正号或负号)空格输出值为正时冠以空 格,为负时冠以负号 # 对c,s,d,u类无影响;对o类, 在输出时加前缀o;对x类,在输出时加前缀0x;对e,g,f 类当结果有小数时才给出小数点 3.输出最小宽度 用十进制整数来表示输出的最少位数。 若实际位数多于定义的宽度,则按实际位数输出 ,若实际位数少于定义的宽度则补以空格或0。
格式输出函数printf() • 4. 精度 • 精度格式符以“.”开头,后跟十进制整数。 • 意义是: • 如果输出数字,则表示小数的位数; • 如果输出的是字符,则表示输出字符的个数; • 若实际位数大于精度数,则截去超过的部分。 • 5. 长度 • 长度格式符为h,l两种,h表示按短整型量输出,l表示按长整型量输出。
格式输出函数printf() 注意: 1. 格式字符串是以%开头的字符串,可由格式字符串和非格式字符串两种组成,其中格式控制字符串用于指定输出格式。 2. 在%后面跟有各种格式字符,以说明输出数据的类型、形式、长度、小数位数等。 3. 非格式字符串在输出时原样照印,在显示中起提示作用。 4. 输出表列中给出了各个输出项, 要求格式字符串和各输出项在数量和类型上应该一一对应。
格式输入函数scanf() 1. scanf()函数的一般形式 scanf(“格式控制字符串”,地址列表); 其中,格式控制字符串的作用与printf函数相同,但不能显示非格式字符串, 也就是不能显示提示字符串。 地址列表,用来接受数据各变量的地址。 变量的地址表示如下: & 变量名 例如: &a,&b分别表示变量a和变量b 的地址
格式输入函数scanf() 例: main() { int a,b,c; printf("input a,b,c\n"); scanf("%d%d%d",&a,&b,&c); printf("a=%d,b=%d,c=%d",a,b,c); }
格式输入函数scanf() 2. 格式字符串 格式字符串的一般形式为: %[*][输入数据宽度][长度]类型字符 其中有方括号[]的项为任选项。各项的意义如下: (1) 类型字符 表示输入数据的类型,其格式符和意义如下所示: d 输入十进制整数 o 输入八进制整数 x 输入十六进制整数 u 输入无符号十进制整数 f或e 输入实型数(用小数形式或指数形式) c 输入单个字符 s 输入字符串
格式输入函数scanf() 2. “*”符 用以表示该输入项读入后不赋予相应的变量,跳过该输入值。 如 scanf("%d %*d %d",&a,&b); 输入为:1 2 3 把1赋予a,2被跳过,3赋予b。 3.宽度 用十进制整数指定输入的宽度(即字符数)。 例如: scanf("%5d",&a); 输入: 12345678 只把12345赋予变量a,其余部分被截去。 又如: scanf("%4d%4d",&a,&b); 输入:12345678将把1234赋予a,而把5678赋予b。
格式输入函数scanf() 4.长度 长度格式符为l和h,l表示输入长整型数据(如%ld)和双精度浮点数(如%lf)。h表示输入短整型数据。 例如: main() { int a; long b; double x; scanf(“%d%ld%lf”,&a,&b,&x); printf(“a=%d, b= %ld,x=%lf”,a,b,x); }
格式输入函数scanf() 3. 使用scanf函数还必须注意以下几点: (1) scanf函数中没有精度控制 。 如:scanf(“%5.2f”,&a); 是非法的。 (2)scanf中要求给出变量地址, 如: scanf(“%d”,a);是非法的。 (3) 在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔则可用空格,TAB或回车作间隔。 例如:scanf(“%d%d”,&a,&b); 输入: 12 10 或 12 10
格式输入函数scanf() (4)在输入字符数据时,若格式控制串中无非格式字符,则认为所有 输入的字符均为有效字符。 例如: scanf("%c%c%c",&a,&b,&c); 输入为:d e f 则把'd'赋予a, ‘’'赋予b,'e' 赋予c。 只有当输入为: def 时,把'd'赋于a,'e'赋予b,'f'赋予c。 如果在格式控制中加入空格作为间隔, 如 scanf ("%c %c %c",&a,&b,&c); 输入时各数据之间可加空格。
格式输入函数scanf() (5)如果格式控制串中有非格式字符则输入时也要输入该非格式字符。 例如: scanf("%d,%d,%d",&a,&b,&c); 其中用非格式符“, ”作间隔符,故输入时应为: 5,6,7 又如: scanf("a=%d,b=%d,c=%d",&a,&b,&c); 则输入应为: a=5,b=6,c=7
格式输入函数scanf() (6)如输入的数据与输出的类型不一致时,虽然编译能够通过,但结果可能不正确。 void main() { int a; printf("input a number\n"); scanf("%d",&a); printf("%ld",a); } 由于输入数据类型为整型, 而输出语句的格式串中说明为长整型,因此输出结果和输入数据不符。
格式输入/输出---例题 例1:为float类型变量a、b输入数据1.2和2.3,下列哪一组是正确的( )。 A、scanf(%f%f,&a,&b); 输入1.2,2.3 B、scanf(″%2.1f%2.1f″,a,b); 输入1.2,2.3 C、scanf(″%f,%f″,&a,&b); 输入1.2,2.3 D、scanf(″%f%f“,&a,&b); 输入1.22.3 √ 例2: 编一程序输入一个正整数,输出它的16进制数 main() { int n; scanf(“%d”,&n); printf(“%x”,n); }
四、通过文件输入/输出 • 所谓文件—— 存储在外部介质上的数据的集合,例如:存储在磁盘上。 • C语言把文件看作是一个字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。 • C语言中的文件存储方式分为 :ASCII文件 和 二进制文件 • ASCII文件(文本文件) : 每个字节存放一个ASCII代码,代表一个字符 • 二进制文件: 把内存中的数据按其在内存中的存储形式原样输出到 磁盘上存放。
四、通过文件输入/输出 ASCII存储形式(5个字节) 例. 整数 10000 的存储: 00110001 00110000 00110000 00110000 00110000 内存存储形式 '1' ' 0' ' 0' ' 0' ' 0' 00100111 00010000 00100111 00010000 二进制 存储形式(2个字节) 10000的二进制形式 其中: ' 0 '-----ASCII码为 48(对应编码为110000) ' 1' -----ASCII码为 49 (对应编码为110001) ASCII文件便于字符处理和输出,二进制文件节省存储空间。 说明: 1. 一个文件是一个字符流或 二进制流。 2. C 语言中对文件的存取是以字符(字节)为单位的,输入输出数据流仅受程序控制,不受物理符号控制(如:回车,换行符), 称这样的文件为 流文件。
四、通过文件输入/输出 C 语言处理文件通常使用——缓冲文件系统 缓冲文件系统—— 系统自动地在内存中为每个正在使用的文件名开辟一个 缓冲区。用于处理文本文件(字符流)。 程序数据区 <===> (输入、输出)文件缓冲区 <===>磁盘文件 标准的 C 语言只采用缓冲文件系统 :既可以处理文本文件,也可以处理 二进制文件。 C语言中对文件的读写都是用库函数来实现。
文件类型指针 每个被使用的文件都在内存中开辟一个区,用来存放文件的有关信息(如:文件的名字 、文件状态与文件当前位置等)。这些信息保存在一个 结构体类型的变量中。 结构体类型是由系统定义的,名为 FILE。 Turbo C 在 stdio.h文件中有以下的文件类型声明: typedef struct { char level ; /* 缓冲区"满"或"空" 的程度 */ unsigned flags ; /* 文件状态标志 */ char fd ; /* 文件描述符(文件号) */ unsigned char hold ; /* 如无缓冲区不读取字符 */ char bsize ; /* 缓冲区大小 */ unsigned char *buffer ; /* 数据缓冲区的位置 */ unsigned char *curp ; /* 指针,下一个字符的位置 */ unsigned istemp ; /* 临时文件,指示器 */ char token ; /* 用于有效性检查 */ } FILE ;
文件类型指针 有了FILE 类型之后,就可以用它来 定义FILE类型的变量。例如: FILE *fp; 表示定义了一个指向FILE 类型结构体的指针变量 fp,可以使 fp指向某个文件的结构体变量,从而通过该结构体变量中的文件信息来访问该文件。也就是说,通过文件指针变量能够找到与它相关的文件。 如果有n 个文件,一般应该设n 个指向FILE 类型结构体的指针变量,使它们分别指向n 个文件,以实现对文件的访问
文件的打开与关闭 • 1. 文件的打开( fopen函数 ) • C语言中用 fopen( ) 函数来实现打开文件, fopen 函数的调用方式为 : • FILE *fp; • fp = fopen(文件名,使用文件方式) ; • 例如: fp=fopen("a1","r"); • 说明: ⑴ a1为文件名 , 是字符串。称为外部文件名。 • ⑵ 使用方式为: 只读方式。 • ⑶ fopen 函数带回指向文件a1 的指针,并赋给 fp,使得 fp指向a1。 fp 称为内部文件名。
文件的打开与关闭 通过 fopen( ) 使内部文件名和 外部文件名联系上,即fp 指向 a1文件。 在打开一个文件时,通知给编译系统有以下3个信息: ①需要打开(即访问)的文件名。 ②使用文件的方式。 ③让哪一个指针变量指向被打开的文件。 如果 fopen 函数打开文件失败,则返回一个空指针值 NULL。
文件的打开与关闭 为避免因上述原因的出错,造成对文件读写操作出错,常用以下的方法来打开一个文件,以确保对文件读写操作的正确性: if((fp=fopen("c:\\myfile.dat","w+"))==NULL) { printf("Cannot open file the file exit!"); exit(0); /* 退出程序 */ } ┇ /* 此处编写打开文件后,对文件读\写的代码 */ 注意:指定文件路径要使用“盘符:\\文件夹名\\文件名”形式
文件的打开与关闭 • 2. 文件的关闭(fclose函数 ) • 关闭文件 ——就是使文件指针不再指向该文件,即使文件指针变量与文件“脱钩”。 • C 语言中用 fclose( ) 函数来关闭文件, fclose 函数的调用形式是 : • fclose (文件指针) ; • 例如 : fclose(fp) ;关闭 fp 所指向的文件 • 如果fclose 函数关闭文件成功,则返回零值;如果fclose 函数关闭文件失败,则返回非零值EOF( -1),EOF为文件结束符。
文件的读写 在C语言中提供了多种文件读写的函数: ▲字符读写函数: fgetc和fputc ▲字符串读写函数:fgets和fputs ▲格式化读写函数:fscanf和fprinf 数据块读写函数:freed和fwrite
文件的写操作 函数fprintf()、fputs()、fputc()和fwrite()均为文件的写操作函数,它们在stdio.h头文件中的原型定义形式如下: int fputc(int ch,FILE *fp); int fputs(char *string,FILE *fp); int fprintf(FILE *fp,char *format,<variable-list>); int fwrite(void *buf,int size,int count,FILE *fp); • 1. fputc函数—— 把一个字符写到 磁盘文件上去, • 调用方式为 : fputc(ch , fp); • 功能:其作用是 将字符(ch 的值)输出到fp 所指向的文件中去。如果输出成功,则返回 ch字符;否则,返回 EOF (即 -1)。 例:输入5行字符,将其写入到C盘根目录的myfile.txt文件中
文件的写操作 #include <stdio.h> void main() { FILE *fp; char ch[80],*p=ch; int n; fp=fopen("c:\\myfile.txt","w"); /* 打开文件*/ printf("input a string:\n"); for(n=1; n<=5; n++) { gets(p); /* 输入一行字符 */ while (*p!='\0') /* 逐个字符写入文件 */ { fputc(*p,fp); p++; } fputc('\n',fp); /* 写入换行符 */ } fclose(fp); }
文件的写操作 2.字符串写函数fputs() fputs函数是向指定的文件输出一个字符,其使用格式: fputs(str, fp); 其中,fp为定义的文件指针变量;str可以是指向字符串的指针变量、字符数组名或字符串常量。例如: fputs("China",fp); 操作成功,函数返回0;写操作失败,返回非0。 例:输入5行字符,将其写入到C盘根目录的myfile.txt文件中
文件的写操作 例:输入5行字符,将其写入到C盘根目录的myfile.txt文件中 #include<stdio.h> void main() { FILE *fp; char ch[80],*p=ch; int n; fp=fopen("c:\\myfile.txt","w"); /* 打开文件*/ printf("input a string:\n"); for(n=1;n<=5;n++) { gets(p); /* 输入一行字符 */ fputs(p,fp); /* 写入该行字符 */ fputc('\n',fp); /* 写入换行符 */ } fclose(fp); }
文件的写操作 3.格式化写函数fprintf() 把格式化的数据写到文件中,其中格式化的规定与printf()函数相同,所不同的只是fprintf()函数是向文件中写入,而printf()是向屏幕输出。如: fprintf(fp,"s=%f,i=%d\n",s,i); 其返回值为实际写入文件中的字符个数(字节数);如果写错误,则返回一个负数。 例题:计算数列1,-1/3!,1/5!,-1/7!,1/9!,...的和至某项的绝对值小于1e-5时为止(该项不累加),将求和的结果以格式"%.6"写到考生目录下新建文件design.dat。
文件的写操作 例题:计算数列1-1/3!+1/5!-1/7!+1/9!,...的和至某项的绝对值小于1e-5时为止(该项不累加),将求和的结果以格式"%.6"写到考生目录下新建文件design.dat。 #include <stdio.h> #include <math.h> void main() { FILE *p; float s=1,t=1,i=3; // // // // // // // // } p=fopen("design.dat","w"); while(fabs(t)>1e-5) { t= -1/((i-1)*i)*t; s=s+t; i+=2; } fprintf(p,"%.6f",s); fclose(p);
文件的读操作 标准C提供的文件读操作函数有fgetc()、fgets()、fscanf()和fread(),它们在stdio.h头文件中的原型定义形式如下: int fgetc(FILE *fp); char * fgets(char *string,int n,FILE *fp); int fscanf(FILE *fp,char *format,<address-list>); int fread(void *buf,int size,int count,FILE *fp); 说明: (1)对于读操作,在文件内部有一个位置指针,用来指向文件的当前读的字节。在文件打开时,该指针总是指向文件的第一个字节。当读取一个数据(字符、一字符串,一个整数或一块数据),该位置指针将自动向后移动到下一个数据位置。
文件的读操作 (2)对于文本文件,由于它的结束标记是EOF(即-1)因此通常判断文本文件是否写完通过读取的字符是不是结束标志来判断。 (3)对于二进制文件,由于没有EOF的结束标志,只能使用系统提供的feof()函数来判断,feof()的使用格式是: feof(fp); 其中,fp是文件指针变量,如果文件读取结束则返回非0值,没结束返回0。所以读写控制通过下面的形式来控制 while( !feof(fp)) { ┇ /* 此处写入读操作语句 */ } (4)文本文件也可使用feof()函数按上面来的形式来判断是否读取结束。
文件的读操作 例如 , 从一个磁盘文本文件顺序读入字符并在屏幕显示出来,程序段如下 .... ch = fgetc ( fp) ; while(ch !=EOF) { putchar( ch ) ; ch = fgetc ( fp ) ; } .... 1. fgetc函数 从指定的文件读入一个字符,该文件必须是以“读”或“读写”方式打开。 调用方式为 :ch = fgetc(fp); fgetc 函数从 fp 所指定文件的当前位置读入一个字符赋给ch;同时,文件的当前位置加 1,如果读入时遇到文件结束符,则返回EOF(即 -1)。 EOF是在 stdio.h 中 定义的符号常量,值为 -1。由于字符的ASCII 码不可能出现 -1,应此定义 EOF 为-1 是合适的。 EOF 不是可输出字符,因此不能在屏幕上显示。用于表示文件结束,只适用于文本文件。
文件的读操作 • 对于 二进制文件,某个字节中的数有可能是 -1,因此难于用 EOF 判断文件是否结束,这时可以用函数 feof( fp)来测试 fp 所指的文件当前是否 “文件结束”,是则返回 1,不是则返回 0。 • 例如 while( ! feof(fp)) { c=fgetc(fp) ; putchar ( c ) ; ….. } feof( ) 也适用于文本文件
文件的读操作 • 2. fgets ( )函数—— 从指定的文件读入一个字符串。 • 调用方式为 : fgets ( str , n , fp) ; • 从 fp 指定的文件中读入一个最大长度为 n-1 的字符串存入字符数组 str,并在数组str 中加 '\0' 作为字符串结束符。如果在读完n-1个字符之前遇到换行符或EOF,读入即结束。 • 如果输出成功 , 则返回 str ,否则 , 返回NULL。
例: 将一个二进制磁盘文件的信息复制到另一个磁盘文件中。 #include <stdio.h> main( ) { FILE *in , *out ; char ch , infile[10] , outfile[10] ; printf("Enter the infile name :\n") ; scanf("%s ", infile) ; printf("Enter the outfile name :\n") ; scanf("%s" , outfile) ; if((in = fopen(infile , " rb")) ==NULL) { printf("cannt open infile\n") ; exit(0) ; } if((out = fopen(outfile , " wb")) == NULL) { printf("cannt open outfile\n") ; exit(0) ; } while( ! feof(in)) { ch=fgetc(in) ; fputc(ch , out) ;} fclose(in) ; fclose(out) ; } 准备工作 打开文件 运行情况如下 : Enter the infile name : file1 <CR> Enter the outfile name : file2 <CR> 复制
文件的读操作 3、fscanf 函数 它们是用于磁盘文件的格式化读的函数, 作用 scanf 类似。 调用方式 : fscanf(文件指针, 格式字符串 , 输入表列 ) ; 例如 :fscanf( fp , "%d , %f" , &k , &x) ; 地址表列 fscanf()常常用于读取fprintf()写入的文件,要注意,格式控件字符串与数据文件数据存放格式一致。