320 likes | 532 Views
学 习 目 标. 1 流与文件. 流的概念 简单的格式控制 简单的文件流操作. 内 容 要 点. 流的概念 输出流、用输出文件 流将数据写入文件 输入流、 用 输入文件 流从文件中读数据. 流的概念. 流 是 C++ 中的重要概念,标准输入输出流( cin , cout ) 和输入输出文件流是常用的流 C++ 中的流实际上是一个字节序列 输入操作是控制序列中的字节内容从一个设备流入内存 输出操作是控制序列中的字节内容从内存流向某个设备 这里的设备可以是键盘、显示器、打印机、磁盘等.
E N D
学 习 目 标 • 1 流与文件 流的概念 简单的格式控制 简单的文件流操作
内 容 要 点 流的概念 输出流、用输出文件流将数据写入文件 输入流、用输入文件流从文件中读数据
流的概念 • 流是C++中的重要概念,标准输入输出流(cin,cout)和输入输出文件流是常用的流 • C++中的流实际上是一个字节序列 • 输入操作是控制序列中的字节内容从一个设备流入内存 • 输出操作是控制序列中的字节内容从内存流向某个设备 • 这里的设备可以是键盘、显示器、打印机、磁盘等
除了针对数据类型的不同操作之外,流还用一些标志来表明该如何操作数据除了针对数据类型的不同操作之外,流还用一些标志来表明该如何操作数据 • 控制输出数据的占位宽度 • 控制输出浮点数的精度 • 可以用函数setiosflags()和resetiosflags()来改变这些标志 • 这些函数和操作包含在头文件iostream或iomanip中,在程序中注意用# include • 用cin、cout处理整数、浮点数、字符等不同类型的数据时,只需用同样的程序语句,这是因为流对不同数据的类型进行了不同的操作
控制符 作用 • dec 控制输出10进制数 • hex 控制输出16进制数 • oct 控制输出8进制数 • setfill (c) c为填充字符 • setprecision(n) 设制n位小数显示精度 • setw(n) 设置n个字符的显示宽度 • setiosflags( ios::fixed ) 固定浮点显示小数 • setiosflags( ios::scientific ) 用指数方式显示小数 • setiosflags( ios::left ) 左对齐显示 • setiosflags( ios::right ) 右对齐显示 • setiosflags( ios::skipws ) 忽略前导空白 • setiosflags( ios::uppercase ) 16进制数用大写字母输出 • setiosflags( ios::lowercase ) 16进制数用小写字母输出
输出流格式控制 • 控制输出宽度 • 为了调整输出,可以通过在流中放入setw操纵符或调用width成员函数为每个项指定输出宽度。
例 使用width函数控制输出宽度 • #include <iostream> • using namespace std; • int main() • { • int i; • double values[ ] = {1.23, 35.36, 653.7, 4358.24}; • for(i=0; i<4; i++) • { • cout.width(10); • cout << values[i] << endl; • } • system("PAUSE");return 0; • }
输出结果是: 演示程序 在一列中以至少10个字符宽按右对齐方式输出 在少于10个字符宽的数值前加入空格
空格是默认的填充符:当输出的数据不能充满指定的宽度时,系统会自动以空格填充空格是默认的填充符:当输出的数据不能充满指定的宽度时,系统会自动以空格填充 • 编程人员可以使用fill成员函数为已经指定宽度的项设置自己需要的填充符 • 若以“*”为填充符,则前面的例子可以修改为如下
#include <iostream> • using namespace std; • int main() • { • int i; • double values[ ] = {1.23, 35.36, 653.7, 4358.24}; • for(i=0; i<4; i++) • { • cout.width(10); • cout.fill('*'); • cout << values[i] << endl; • } • return 0; • }
例 使用setw操纵符指定宽度 • #include <iostream> • #include <iomanip> // 为使用setw操纵符 • using namespace std; • int main() • { • int i; • double values[ ] = {1.23, 35.36, 653.7, 4358.24}; • char *names[ ] = {"Zoot", "Jimmy", "Al", "Stan"}; • for(i=0; i<4; i++) • { • cout << setw(6) << names[i] << setw(10) << values[i] << endl; • } • return 0; • }
输出结果是: setw和width都不截断数值,如果数值超过了指定宽度,则显示全部值(遵守精度设置) setw和width仅影响紧随其后的项,在一项输出完后,宽度恢复成默认值
例 设置对齐方式 • 输出数据时默认的方式是右对齐,可以设置标志使输出按照其他对齐方式 • 使用带参数的函数setiosflags()和resetiosflags()来实现所需要的方式 • setiosflags()不同于setw和width,它的影响是持久的,直到用resetiosflags()重新恢复默认值为止 • 为了使前面的例子实现:姓名左对齐、数值右对齐,我们修改如下:
#include <iostream> • #include <iomanip> • using namespace std; • int main() • { • int i; • double values[ ] = {1.23, 35.36, 653.7, 4358.24}; • char *names[ ] = {"Zoot", "Jimmy", "Al", "Stan"}; • for(i=0; i<4; i++) • { • cout << setiosflags(ios::left) • << setw(6) << names[i] • << resetiosflags(ios::left) • << setw(10) << values[i] << endl; • } • return 0; • }
例 控制输出精度(小数位数) • 浮点数输出精度的默认值是6:如数3466.9768显示为3466.98 • 为了改变精度,可以使用setprecision操纵符及2个标志:ios :: fixed 和 ios :: scientific • 若设置ios :: fixed ,输出为: 3466.976800 • 若设置ios :: scientific,输出为: 3.466977e + 003 • 若设置了ios :: fixed 或 ios :: scientific,则精度值确定了小数点之后的小数位数;若都未设置,则精度值确定了总的有效位 • 可以用resetiosflags()清除这些标志
#include <iostream> • #include <iomanip> • using namespace std; • int main() • { • int i; • double values[ ] = {1.23, 35.36, 653.7, 4358.24}; • char *names[ ] = {"Zoot", "Jimmy", "Al", "Stan"}; • // cout << setiosflags(ios::scientific); • for(i=0; i<4; i++) • { • cout << setiosflags(ios :: left) • << setw(6) << names[i] • << resetiosflags(ios :: left) • << setw(10) << setprecision(1) << values[i] << endl; • } • return 0; • }
#include <iostream> • #include <iomanip> • using namespace std; • int main() • { • for(int i=0;i<10;i++)cout<<i; 0123456789 • cout<<endl; * • for(int x=1;x<=10;x++) ** • cout<<setfill(‘*’) *** • <<setw(x) **** • <<" * “ ***** • << endl ; ****** • return 0; ******* • } ******** • ********* • **********
输出图形 • #include <iostream> • #include <iomanip> • using namespace std; • int main() • { • for(int i=0;i<10;i++)cout<<i; 0123456789 • cout<<endl; * • for(int x=1;x<=9;x++) ** • cout<<setfill(' ') *** • <<setw(10-x) **** • <<"" ***** • <<setfill('*') ****** • <<setw(x) ******* • <<"*“ ******** • <<endl; ********* • cout<<"**********" <<endl; ********** • return 0; • }
#include <iostream> • #include <iomanip> • using namespace std; • int main() • { • for(int i=0;i<=9;i++)cout<<i; 0123456789 • cout<<endl; ********* • for(int x=1;x<=5;x++) ******* • cout<<setfill(' ') ***** • <<setw(x) *** • <<" " * • <<setfill('*') • <<setw(11-2*x) • <<"*“ • <<endl; • return 0; • }
改变整数的进制 • 请同学们课后自学课本的相关内容 • 第2版教材:pp.193-194 • 第1版教材:pp.220-221 • 要求:读懂程序、能理解课本的解释内容、上机练练、做到会用
文件 • 程序中各种常量和变量的值只在程序运行时有效,要把这些数据永久地保存下来,可以用文件的形式 • 所写的程序,可以在编程环境的支持下以文件的形式保存在磁盘上,也可以从磁盘上读入到编程环境中 • 在C++程序中进行文件处理,要包含头文件fstream
用输出文件流将数据写入文件 • 把数据输出到文件要用输出文件流,建立与某个文件相关联的输出文件流,可以用语句 • ofstream 变量名 (“文件名”) • ofstream是数据类型,表示输出文件流,用来声明该类型的变量 • (“文件名”):除文件外还可以写上自己需要的路径,默认的是当前的路径 • 例如: • ofstream outtomyfile (“Student.txt”); • ofstream outtomyfile (“C:\Student.txt”);
也可以先建立输出文件流,再与具体文件相关联,如:也可以先建立输出文件流,再与具体文件相关联,如: • ofstream outtomyfile; • outtomyfile.open (“Student.txt”); • 在将流与文件关联之后,还要测试文件是否已被正确打开 • 操作系统对同时打开的文件数目的限制 • 不同程序试图打开同一文件的访问冲突 • 完成文件操作之后,应该将文件关闭 • outtomyfile.close();
用输入文件流从文件中读取数据 • 从文件中读取数据可用输入文件流,建立与某个文件相关联的输入文件流,可以用语句 • ifstream 变量名 (“文件名”) • ifstream是数据类型,表示输入文件流,用来声明该类型的变量 • (“文件名”):除文件外还可以写上自己需要的路径,默认的是当前的路径 • 例如: • ifstream infrommyfile (“Student.txt”); • ifstream infrommyfile (“C:\Student.txt”);
例8.6演示 • 将学生数据写入到一个文本文件中(student.txt) • 例8.7演示 • 从文本文件(student.txt)中将学生数据读入到内存中,并显示到屏幕上
补充1 二进制文件的读写操作 • 二进制文件打开方式中应指定:ios::binary • 写二进制文件使用成员函数:write( ) • 读二进制文件使用成员函数:read( ) • 这两个函数定义在fstream.h中原型分别为: • ostream& write( const char*pch, int n ); • istream& read( char* pch, int n ); • 第1个参数要读写的字符指针,即字符串,向文件中写时,字符串不能被改变; • 第2个参数为要读写字符的个数。 • 函数的使用格式为: • 二进制内部文件名.write(待写入的字符串地址,字符串长度) • 二进制内部文件名.read(字符串读入地址,字符串长度)
【补充例题】使用成员函数read、write写读二进制文件【补充例题】使用成员函数read、write写读二进制文件 • 将前述的学生结构数据用二进制形式保存在文件student.bin中 演示补充例题8.1(写二进制文件) 演示补充例题8.2(读二进制文件) 与学生讨论:二进制文件与文本文件的区别
补充2 随机文件的读写操作 • 从文件头开始读或从文件尾开始写,称为顺序读写 • 在文件的任意位置进行读写操作,称为随机读写操作,可随机读写的文件称为随机文件。 • 随机读写文件需要: • ①按读写方式打开文件 • ②使用定位函数将读写指针定位到所需位置,读写指针只有一个,但是有读、写两组函数对它进行操作 • ③使用读写函数对文件进行读写 • 读指针定位的成员函数为:seekg( ) • 其原型为 istream& seekg( 位置 ); • istream& seekg( 偏移量 ,参照位置); • 其中位置和偏移量为长整数,参照位置为下列3个之一: • ios::beg(值为0)、ios::cur(值为1)、ios::end(值为2) • 分别表示文件开头、当前位置、文件结尾
写指针定位的成员函数为:seekp( )其原型为 ostream& seekp( 位置 ); ostream& seekp( 偏移量 ,参照位置);其中位置和偏移量为长整数,参照位置为下列3个之一:ios::beg(值为0)、ios::cur(值为1)、ios::end(值为2)分别表示文件开头、当前位置、文件结尾取当前读指针位置的成员函数原型为:long teelg( )取当前写指针位置的成员函数原型为:longteelp( )这两个取指针位置函数返回的长整数表示读写的当前位置距离文件开头的字节数。一般指针定位、取指针位置的函数的使用格式为:内部文件名.seekp(偏移量,参照位置)内部文件名.seekg(偏移量,参照位置)内部文件名. tellg( )、内部文件名. tellp( )④文件读写结束应注意使用close函数关闭文件
【补充例题】使用成员文件读写指针函数,随机写读二进制文件【补充例题】使用成员文件读写指针函数,随机写读二进制文件 • 对前述用二进制形式的学生结构数据文件student.bin进行随机定位读写 演示补充例题8.3(随机读写二进制文件) 与学生讨论:随机文件与顺序文件的区别
小结与作业 C++中所有的输入与输出均用流来表示 输入与输出应注意流出的发源地与流向目的地 所有对于流的操作均由流对象来实现 屏幕作为输出设备是流向的目的地,用cout表示 键盘作为输入设备是流的发源地,用cin表示 插入符<<是向流对象中输出 提取符>>是从流对象中获取,保存在内存中 文件分内部文件、外部文件,分文本文件、二进制文件,分顺序读写文件、随机读写文件 内部文件就是流对象,由C++处理 外部文件由操作系统处理,保存在外存中