c中 不能用print(“%自己定义的结构体”,结构体变量);
因此 c++ 建立了字节的文件i/o系统 通过重载运算符 << ,>>作为输出输入运算符 使其能识别用户创建的类型 在书写形式上 比c的i/o系统简单 清晰
主要有 流的输入输出
一般形式的输入输出
格式化的输入输出
文件输入输出

c++的i/o流的基本概念
流是c++为输入输出提供的一组类 称为流库 流是与文件 和外部设备 相联系的 通过使用流定义的方法 就能够完成对文件和设备的输入输出操作
c++的i/o流库是以类层次 的方式实现的 它包含两个平行的基类 streambuf 和ios 所有的流类由他们派生 streambuf类提供 物理设备的接口 ios 类提供用户使用流类的接口 ios类派生出许多流类 使用者接触的 是由派生类定义的高层次 的I/O函数
基类ios直接派生出 四个基本类 istream ostream fstreambase streambase 在此基础上组合出多个实用流 输入输出流 输入输出文件流 输入输出串流
类的继承关系结构

主要的继承关系
cin 和cout是实现输入输出 标准输入输出流
c++有四个预定义的标准流 当c++开始执行程序时 他们会自动打开 这四个预定义的流是
标准输入流 cin;
标准输出流 cout;
非缓冲型标准出错流 cerr;
缓冲型标准出错流 clog;
前两个流是与标准输入设备和标准输出设备 相关的流 c++的标准输入输出设备 默认为键盘 和显示器 但他们能由程序或操作系统重定向
缓冲型标准出错流和非缓冲型标准出错流的区别在于没有缓冲的时候 送给流的内容立即输出 缓冲型的要等缓冲区满才输出火强迫输出
为输出流重载的操作符<<称为 插入操作符 使用时 可以在输出流上插入 字节 输入流重载的操作符>>称为提取操作符使用时可以在输入流上提取字节 这两个重载操作符 分别定义在类ostream 和istream中
操作系统提供一种I/O的重定向技术 可以将标准输入输出设备交换的信息改为与其他设备交换信息 例如 在操作系统下 用户用命令行 运行程序 prog
prog>outfile
可以使程序中所有对标准输出设备的输出都改向输出到磁盘文件 outfile
但是这里会产生一个问题 就是程序中原来必须显示在屏幕上的信息 如提示信息 现在看不到了 因为这些信息 也被重定向到磁盘文件了 这很不方便 这个问题可以用标准出错流 cerr来解决 标准出错设备是不会重定向的 例如原来程序中有如下提示语句
cout<<“enter a string”;
可改为
cerr<<“enter a string”;
输入输出 操作符的使用
c++把数据传送操作的设备看作是对象在流类文件 iostream 中 定义了流的对象 cin 和cout cin代表输入设备 cout代表输出设备 istream类和ostream类中分别重载了右移运算符 >> 左移运算符 <<前者称为提取操作符 后者称为插入操作符
使用插入操作符 他的左操作数使代表输出设备的对象 右操作符是输出的内容把数据写到标准输出设备(显示屏 )格式
cout<<输出项;
输出项可以是 常量 变量 转义字符
使用提取操作符 他的左操作数 代表输入设备的对象 右操作是内存缓冲区变量 从标准输入流对象 cin 键盘 向变量送数据的格式
cin>>变量;
输出运算符 允许多个输出操作结合在一个语句中 并且采用做结合方式
输入运算符 也允许多个输入变量组合在一个语句中
输入数据 数据之间要用空格分开 输入字符串时 字符串中间不能有空格 还要注意输入的数据类型要与变量类型匹配
用户自定义插入操作符和提取操作符
重载即可
设class A {
public:
int i,j,k;
set_val(int a)
{
i=j=k=a;
}
};
为创建类A的对象的插入操作符函数 其功能为输出类 A对象的数据成员
ostream &operator<<(ostream &out,A obj)
{
out<<obj.i<<",";
out<<obj.j<<",";
out<<obj.k<<"\n";
return out;
}
这个函数返回类型是一个对类ostream 的对象的引用 他有两个参数 第一个参数是对流的引用 第二个参数 是出现在操作符<<的右边的对象 给出一般框架
ostream &operator<<(ostream &函数的流,用户定义类名 对象名)
{
函数代码
return 函数的流;
}
例子

#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
using namespace std;
//class sha {//静态联编 //
//public:
//    void d() { cout << "sha" << endl; }
//    void f() { d(); }
//};
//class ci :public sha {//public:
//    void draw() { cout << "ci" << endl; }
//};
//void main() {//    ci  oneshape;
//    oneshape.f();//这个f就是 sha::f { }
//}
class Base
{public:Base();~Base();virtual void who(){cout << "base  miao\n";}
private:};
class deriv_1: public Base
{public:deriv_1();~deriv_1();void who(){cout << " deriv1  \n" ;}
private:};
class deriv_2 :public Base
{public :void who()//返回类型要一样或协变 参数个数 类型要一致 而且{cout << " deriv2  \n";}
};deriv_1::deriv_1()
{}deriv_1::~deriv_1()
{}Base::Base()
{}Base::~Base()
{}
//int main()
//{//    Base base_obj;
//    Base* b_ptr;
//    deriv_1 d1_obj;
//    deriv_2 d2_obj;
//    b_ptr=&base_obj;
//    b_ptr->who();
//    b_ptr = &d1_obj;
//    b_ptr->who();
//    b_ptr = &d2_obj;
//    b_ptr->who();
//
//    return 0;
//}
class figure
{public:figure();~figure();void set_dim(double i, double j=0){x = i; y = j; r = i;}virtual void show_area() = 0;protected:double x, y,r;
};
class triangle:public figure
{public:triangle();~triangle();void show_area(){cout << "height*0.5*base    :" << x * y * 0.5 << "\n";}
private:};
class rectangle:public figure
{public:rectangle();~rectangle();void show_area(){cout << "height*width   :" << x * y * 0.5 << "\n";}
private:};
class circle:public figure
{public:circle();~circle();void show_area(){cout << 3.1415926 * r * r;}
private:};circle::circle()
{}circle::~circle()
{}
rectangle::rectangle()
{}rectangle::~rectangle()
{}
triangle::triangle()
{}triangle::~triangle()
{}
figure::figure()
{}figure::~figure()
{}//纯虚函数
class functions
{public:functions();~functions();functions(float f) { val = f; }//virtual void output() {}//这个就不是纯虚函数 virtual void output() = 0;
protected:float  val;
};
class func_sin:public functions
{public:func_sin();~func_sin();func_sin(float f) :functions(f){}void output(){cout << sin(val) << endl;}
private:};
class func_cos:public functions
{public:func_cos();~func_cos();func_cos(float f) :functions(f) {}void output(){cout << cos(val)<<endl;}
private:};func_cos::func_cos()
{}func_cos::~func_cos()
{}
func_sin::func_sin()
{}func_sin::~func_sin()
{}
functions::functions()
{}functions::~functions()
{}
//int main()
//{//    func_sin s(0);
//    s.output();
//    func_cos c(0);
//    c.output();
//    return 0;
//}
struct node
{int a;int b;node(int q, int p) :a(q), b(p) {}}pp(1,5);
class A
{public:A(int x, int y):a(x),b(y) {}//这种初始化。。。。就是一种性能 对于类类型数据是一种非常大的提升相比赋值初始化 。~A();int a; int b;
private:};A::~A()
{}
//int main()
//{//    A oo(100 ,415);
//
//    cout << oo.a;
//    cout << oo.b;
//    cout << pp.a;
//    cout << pp.b;
//}
class DA
{public:DA(int a, float b, char c) :i(a),f(b),ch(c){};~DA();int i;float f;char ch;private:};
ostream& operator<<(ostream& out, DA obj)
{out << obj.i << ",";out << obj.f << ",";out << obj.ch << "\n";return out;
}DA::~DA()
{}int main()
{DA A(1, 1.2, 'a');cout << A;return 0;
}

DA 输出格式是由重载插入符决定的
重载插入操作符函数不能是类的成员函数 否则 系统就会认为左操作数 (通过this指针隐式传送)是调用操作符函数的类的对象 但重载插入操作符的左边参数是流 而右边参数是类的对象
不能将插入操作符函数 定义成所操作类的成员对象 就产生一个问题 重载插入操作符不能 访问类的私有函数元素
解决办法将是插入操作符函数定义为类的友元函数
重载提取操作符 和插入操作符一样
格式化I/O
数据的输入和输出格式是由提取操作符 和插入操作符缺省规定的 两种格式化输入方法 第一种方法 使用 ios类的成员函数 第二种 使用一种成为控制器的特殊函数
用ios类的成员函数 实现格式化i/o
在iostream.h文件中定义了如下的枚举类型

#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
using namespace std;
class
{public://
//formating flages  格式标志enum{skipws = 0x0001,//skio white space on input(用于输入)left= 0x0002,//left_adjust output(用于输出 )right=0x0004,//right_adjust output(用于输出)internal= 0x0008,//pad after sign for base indicator(用于输出)dec= 0x0010,//decimal conbersion(用于输出/输入)oct= 0x0020,//octal conversion(用于输出/输入)hex= 0x0040,//gexadecimal conversion(用于输出/输入)showbase= 0x0080,//show integer base on output(用于输出/输入)showpoint= 0x0100,//show decimal point and trailing zeros(用于输出)uppercase= 0x0200,//uppercase hex output(用于输出)showpos= 0x0400,//explicit +with positive intergers(用于输出)//explicit(显式的)scientific= 0x0800,//scientific notation(用于输出)fixed= 0x1000,//floating notation(e.g. 123.45)(用于输出)unitbuf= 0x2000,//flush output after each output operation(用于输出)stdio= 0x4000,//flush output after each character inserted(用于输出)};
};

上述枚举定义的值用于设置或清除 流的格式中的一些控制信息的标志 他们的意义如下
skipws 若设置此标志 提取(输入)操作时跳过空白字符 (空格 制表 新行)
如果清楚这个标志 空白符将不被忽略
left 设置此标志 插入(输出)数据在规定的域宽中左对齐剩余 空间用填充字符填充
right 同上 右对齐
internal 符号左对齐 数据右对齐 其间以空白填充
dec 以十进制显示整数 (缺省值)
oct 以八进制显示整数
hex 以十六进制显示整数
showbase 在显示的整数前加数制基值指示符
showpoint 在显示的浮点数的小数值后写零
uppercase 以大写字母显示数据中的字母
showpos 在显示的正数前加+号
scientific 用科学计数法显示浮点数
fixed 以十进制 小数方式(常规方式 )显示浮点数
unitbuf 在每次插入后刷新流
stdio 每次插入后刷新stdio.h中定义的流
所谓刷新流就是将输出写到流相连的物理设备上
上述格式标志之间是 或的关系 因此可以几个标志并存
格式标志存放在 ios类定义 的长整形数据成员中称为标志字
例如设置skipws和dec两个标志 他们的值分别为 0x0001 和0x0010因为他们在标志字中是以或的关系存储的 所以标志子的值是0x0011
在iostream.h文件的ios类中定义了以下列处理标志的一些成员函数
long flags(void) 返回与流相关的当前标志
long flags(long)返回与流相关的当前标志并设置参数指定的新标志
long setf(long) 返回格式标志的当前值 并设置参数说明的标志
long setf(long,long)返回格式标志的当前值 关闭第二个参数指定的标志设置第一个参数说明的标志
long unsetf(long)返回当前的标志值 并清除参数指定的标志
int width(int) 返回当前域宽并设置新值 (缺省时根据表示它所用的字节数而定)
char fill (char) 返回当前的填充符 (缺省时为空格 )并设置参数指定的新字符
int precision(int)返回现实的小数位 并重新设置参数指定的小数位数
因为上述的每个标志符都是类的ios的数据成员所以在使用他们时要写出他们的作用域
例如 ios::hex 不能单独使用标志
设置状态标志使用setf 一般格式
stream.setf(ios::格式标志)
其中stream时所操作的流 如cin ,cout
例如 设置showbase 标志用于输出
cout.setf(ios::showbase);
同时设置多个标志其方法用或运算将这些标志变成一个新的长整形数据
例如
new_flags=ios::hex|ios::showbase;
cout.setf(new_flags)
应用

#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
using namespace std;
//应用设置标志
int main()
{double d = 123.456789;int  j = 16;//cout.setf(ios::showpos);//设置正数前带+号//cout.setf(ios::scientific);//以科学计数法 显示浮点数 //cout.setf(ios::showbase);//输出数据前带有基数符//cout.setf(ios::hex);//转换基数为十六进制 cout.setf(ios::showbase | ios::scientific | ios_base::hex | ios::showpos);cout.setf(ios_base::oct, ios_base::basefield);//vs 除非知道当前没有设置基标志,否则 ios::setf(_IFlags) 不应和 ios::dec、ios::oct 或 ios::hex 的标志值一起使用。格式化的输入/输出函数和运算符假定只设置了一个基。改用 ios_base。例如,setf( ios_base::oct, ios_base::basefield ) 清除所有基信息并将基设置成八进制。cout << d << endl;cout << j ;return 0;
}
int main()
{double d = 123.456;double f = 4567.89;cout.setf(ios::showpoint);//设置浮点数输出带小数0cout.setf(ios::fixed);//使用定点形式cout.precision(5);//精度 5位小数cout.width(20);//数据宽度 20cout.fill('#');//填充字符cout << d << endl;cout.width(20);cout << f << endl;cout.width(20);cout.precision(1);cout.fill('&');cout << d << endl;cout.width(20);cout << f << endl;return 0;
}

取消状态标志 用unsetf函数 其一般形式
stream.unsetf(ios::格式符号)
取状态标志 一般格式用 flags函数
stream.flags(ios::格式标志 )

#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
using namespace std;
//应用设置标志
//int main()
//{//  double d = 123.456789;
//  int  j = 16;
//  //cout.setf(ios::showpos);//设置正数前带+号
//  //cout.setf(ios::scientific);//以科学计数法 显示浮点数
//  //cout.setf(ios::showbase);//输出数据前带有基数符
//  //cout.setf(ios::hex);//转换基数为十六进制
//  cout.setf(ios::showbase | ios::scientific | ios_base::hex | ios::showpos);
//  cout.setf(ios_base::oct, ios_base::basefield);//vs 除非知道当前没有设置基标志,否则 ios::setf(_IFlags) 不应和 ios::dec、ios::oct 或 ios::hex 的标志值一起使用。格式化的输入/输出函数和运算符假定只设置了一个基。改用 ios_base。例如,setf( ios_base::oct, ios_base::basefield ) 清除所有基信息并将基设置成八进制。
//  cout << d << endl;
//  cout << j ;
//
//  return 0;
//}
//设置域宽小数点和填充数
//int main()
//{//  double d = 123.456;
//  double f = 4567.89;
//  cout.setf(ios::showpoint);//设置浮点数输出带小数0
//  cout.setf(ios::fixed);//使用定点形式
//  cout.precision(5);//精度 5位小数
//  cout.width(20);//数据宽度 20
//  cout.fill('#');//填充字符
//  cout << d << endl;
//  cout.width(20);
//  cout << f << endl;
//  cout.width(20);
//  cout.precision(1);
//  cout.fill('&');
//  cout << d << endl;
//  cout.width(20);
//  cout << f << endl;
//
//  return 0;
//}
//取状态标志和消除状态标志
void outflags(int  f);//函数原型
void outflags(int f)
{int  l;for (l = 0x8000; l; l = l >> 1)//右移一位/2{if (l & f)cout << "1";else{cout << "0";}}cout << endl;
}
int main()
{int  f;f = cout.flags();//取当前状态标志字outflags(f);//输出当前状态标志字cout.unsetf(ios_base::unitbuf);//消除状态标志字cout.unsetf(ios_base::skipws);//cout.unsetf(ios_base::uppercase);//f = cout.flags();//取当前状态标志字outflags(f);//输出当前状态标志字cout.setf(ios_base::dec, ios_base::basefield);cout.setf(ios_base::showpos | ios_base::scientific | ios_base::dec, ios_base::basefield);//cout.setf(ios_base::showpos);cout.setf(ios_base::scientific);f=cout.flags();//取状态标志字outflags(f);//输出状态标志字return 0;}

使用 控制器 函数实现格式化

为了使用控制器函数 程序需要包含头文件 iomanip.h//io操作机器人

控制器 含义 输入/输出
dec(decimalism) 格式为十进制的数据 输入及输出
endl 输出换行符兵刷新流 输出
ends 输出一个空字符 输出
flush 刷新一个流程 输出
hex 格式为十六进制的数据 输入及输出
oct 格式为八进制的数据 输入及输出
restflags 关闭f中说明的标志 输入及输出
setbase(int base) 设置数据的基数 输出
setfill(int ch) 设置填充符 输入及输出
setiosflags(long f) 设置f中说明的标志 输入及输出
setprecison(int p) 设置显示小数位数 输入及输出
setw(int w) 设置域宽 输入及输出
ws 跳过开头的空白符 输入

控制器函数是一种类似于函数的运算符他可以嵌入输入输出操作链中

#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
#include<iomanip>
using namespace std;
int main()
{cout << setprecision(3) << 1.3456 << endl;cout << setw(20) << "hello there" << endl;cout << setiosflags(ios::scientific);cout << 1.345 << endl;cout.setf(ios::showbase);cout << hex << 256 << endl;return 0;
}

注意 控制器在I/O操作链中的位置 当控制器不带参数时调用它时不能带括号 两种格式化方式在一个程序中可以同时使用
建立自己的控制器 函数
利用系统定义的控制I/O格式的函数 我们可以建立自己的控制器函数 这里所讲的都是不带参数的
1.输出控制器
所有无参数输出控制器函数均有如下的结构
ostream &控制器函数名(ostream &函数操作的流)
{
函数代码
return 函数操作的流 ;
}
虽然定义的控制器函数 有操作流类型的参数 但当他将用于输出操作时并不带参数
输入控制器类似
所有无参数的输入控制器
istream &控制器函数名 (istream &控制器操作的流)
{
控制器函数的代码
return 控制器操作的流;
}

#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
#include<iomanip>
using namespace std;
ostream& new_from(ostream& new_stream)
{new_stream.precision(3);//从第一个非零保留new_stream.setf(ios::right);new_stream << setw(20) << setfill('*');return new_stream;
}
istream& prompt(istream& my_stream)
{my_stream >> dec;cout << "enter a float value";return my_stream;
}
int main()
{cout << "12345678901234567890" << endl;float f;//float f = 10.0123;cin >>prompt>> f;cout << f << endl;cout << new_from << f << endl;return 0;
}

文件的I/O
c++ 中 提供了另一套 文件的输入输出工具
c++的输入输出操作是通过他的I/O流库实现的 c++把数据传送操作称为流 数据从内存传送到外部 叫做输出流 数据从外部传送到内存 叫做输入流
c++定义 有三种六文件 文件输入流类 ifstream 文件输出流类 ofstream
文件输入输出流类这些文件都定义在头文件 fstream 这些类 分别定义了输入方式 输出方式 输入输出方式访问文件 所需要的所有文件 执行文件的输入输出 必须包含头文件 fstream.h
通过系统定义的流类 可以定义我们 所需要的流类型的对象
为了读写文件 首先必须通过 打开 文件操作 建立流与文件的联系 然后才能进行输入 输出操作 文件读写完毕后还要通过关闭操作撤销文件与流的联系
打开和关闭文件
打开文件就是将文件与创建的流对象联系起来 使其能够进行读写文件的操作
关闭文件就是断开他们之间已存在的联系 使之不能进行文件的读写操作
打开文件
两种打开文件的方法
open()
函数打开方法
void open(char *filename ,int mode,int access);
这里filename 时需要打开的文件名 可包含路径 文件名要用双引号括起来 mode的值 代表文件打开的模式 必须是以下的一个或多个值
ios::app 添加方 式 向 文件输出的内容加到文件尾
ios::ate 文件打开时文件指针置于文件尾
ios::in 文件打开方式为输入方式 (istream的隐含方式(缺省值))
ios::nocreate 若文件不存在则打开失败 否则成功
ios::noreplace 若文件存在则代开失败 否则成功
ios::out 文件打开方式位输出方式(ostream的隐含方式(缺省值))
ios::trunc 若文件存在则清除其内容 文件长度压缩为0 若文件不存在则以写方式打开文件
可通过 或 操作将其中多个值模式结合起来
access 的值决定文件的访问方式 它可以取 下面的一个或多个值
0 普通文件打开访问(缺省值)
1 只读文件
2隐藏文件
4系统文件
8文档定位文件
同样access的值也可以通过或操作将多个值连接起来
打开文件的一般格式
定义流类的对象 ;
流类对象.open(“文件名”,mode,access);
access的默认值为 0 ifstream的缺省值ios::in, ofstream的缺省值ios::out
如果调用 open()函数失败 流变量的值为0
fstream mystream;
mystream.open(“test”,ios::in|ios::out);
if(!mystream)
{
cout<<“can’t open file”;
后续处理
}
利用构造函数打开文件
c++的ifstream ofstream 和fstream 三个流类 均定义了自动打开文件的构造函数 构造函数的参数及默认值 都与上面的函数open()相同 打开文件失败流变量都是0
关闭文件
关闭文件要使用流泪的成员函数
一般形式为
流类对象.close();
函数close()不带参数 而且没有返回值
文件的读和写
用插入操作符<<和提取操作符>>读写文本文件
文件打开后 只要使用插入操作符 和提取操作符
检测文件尾
在文件的I/O操作中 读取一个文件 可能需要检测是否读到文件的尾部 这个检测可用 eof()函数实现 该函数的原型
int eof()
到达文件尾时返回一个非零值 否则返回零值
使用 get 和put 函数读写文本文件
get() put() 是文件流类的两个成员函数通过这两个函数就可以实现文本文件的按字符的读写
get() 函数的原型
ifstream &get(char &ch)
函数get的功能是 从流中 读出一个字符 返回此流
put()函数的原型
ofstream &put(char ch)

二进制文件的读和写
前面 有关文件的打开与关闭的内容 对于二进制文件仍然适用
为实现读二进制数据 可用c++ 流类函数成员 read() 为实现写二进制文件 可使用 流类成员函数 和write() 他们的原型分别为
ifstream &read(unsigned char *buf,int num)
ofstream &write(unsigned char *buf,int num)
函数read 的功能 从流中读取num个字节数据并存放到指针buf所指的缓冲区中 函数返回该流 当达到文件尾时 该流变为0
write 函数的功能 将buf所指的缓冲区num个字节 的数据写入流中 并返回该流 一般可用被读写的数据的存储区地址作为读写缓冲区的指针buf 读写数据的字节数通常可以方便的使用函数sizeof得到

文件的随机访问
c++的流I/O系统为文件的随机访问 提供了一些函数 利用这些函数可以在文件的任何位置进行读和写
在c++的I/O系统中 对应一个函数有两个指针 一个是读指针它说明输入操作在文件中的位置 另一个是写指针 它说明下次写操作的位置 每次执行读或写操作时 相应的指针自动增加到下一个读写位置
在流I/O 中有两个函数用于设置访问文件的指针位置 他们是流类的成员函数 seekg()和seekp() 函数seekp对应于写指针(文件输出 ) 使用函数seekg()和seekp() 就可以任意改变上述指针的位置 从而实现非顺序地(即随机地) 操作文件中的数据 这个函数有以下两种格式
seekg(long pos)
seekg(long off,dir)
seekp(long pos)
seekp(long off ,dir)
函数seekg(pos) 的功能是将文件的读指针从文件头 开始移动 pos个字节的位移量 参数pos 为一long型量
函数 seekg(off,origin)和seekp(off,origin)
参数orgin是文件指针移动的起始位置 off为指针相对位移量 这两个函数的功能分别是将读指针和写指针 从origin位置移动off个字节的位移量 参数origin只能取表的给定值

origin 意义
ios::beg 文件头
ios::cur 当前位置
ios::end 文件尾

与随机文件相关的函数还有tellg() 和函数tellp() 其中tellg用于输入文件
tellp用于输出文件 他们的功能是返回文件读写指针的当前位置 设当前打开的输入流对象是in 使用下面语句 可以输出当前读指针的位置
cout<<in.tellg();

#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
#include<fstream>
#include<iomanip>
using namespace std;
//int main()
//{//  std::ofstream out("outfile",ios::out);
//  if (!out)
//  {//      cout << " no scram 1";
//      return 1;
//  }
//  ifstream in;
//  in.open("infile",ios::in);
//  if (!in)
//  {//      cout << "no scram 2\n";
//      return 1;
//  }
//  in.close();
//  out.close();
//
//  return 0;
//}
istream& prompt(istream& stream)
{stream >> dec;cout << "enter ";return stream;
}
ostream& new_form(ostream& stream)
{stream.precision(3);stream.setf(ios::right);stream << setw(20) << setfill('*');return stream;
}
int main()
{/*ofstream out("myfile1");if (!out){cout << "scram2 \n";return 1;}float f = 1.2345;int i = 10;char c = 'a';cin >> prompt >> i >> f >> c;out << new_form << i << endl;out   << new_form << f << endl;out << i << " " << f << " " << c << endl;out << "this is my_file1" << endl;out.close();*/ofstream out("myfile2");if (!out){cout << "scram2 \n";return 1;}float f;int i;char c;cin >> prompt >> i >> f >> c;out << i << " " << f << " " << c << endl;out << new_form << i << endl;out << new_form << f << endl;out << "this_is_my_file1" << endl;out.close();ifstream in("myfile2");if (!in){cout << "scram\n";return 1;}char cc;int ii;float ff;char str1[80];char str2[80];char str3[80];in >> ii >> ff >> cc;in >> str1;in >> str2;in >> str3;cout << str1 << endl;cout << str2 << endl;cout << str3 << endl;in.close();return 0;}
int main()
{ofstream out("myfile3");if (!out){cout << "scram\n";return 1;}char str[] = "123.45 my data";char* ptr = str;while (*ptr){out.put(*ptr++);}out.close();return 0;
}
int main()
{ifstream in("myfile3");if (!in){cout << "scram\n";return 1;}char ch;//in.get(ch);/*int q = 0;while (in){q++;in.get(ch);cout << ch;cout << q;}*///这里有个细节 应该先get一次 假如有6个字符指针指向第一个读取然后++ 可能某些原因导致和下面不同最后一个字符貌似是空而且ch也不会改变int q = 0;while (in.get(ch))//判断文件尾部是有问题的 这个判断字符就没有这样的问题{q++;cout << ch;cout << q;}//int q = 0;/*while (!in.eof()){q++;in.get(ch);cout << ch;cout << q;}*/  //同第一个问题暂不能解决不知道是前面还是后面多了一个空 in   char pp[]="11111";/*pp[0] = '1';pp[1] = '1';pp[2] = '1';pp[3] = '1';pp[4] = '1';pp[5] = '\0';pp[6] = '1';*/char* p = pp;while (*p){cout << *p++;}in.close();return 0;
}
#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
#include<fstream>
#include<iomanip>
using namespace std;
int main()
{ifstream inf("myfile1");if (!inf){cout << "scram\n";return 1;}ofstream outf("filecopy");if (!outf){cout << "scram \n";return 1;}char c;while (inf.get(c)){outf.put(c);}return 0;
}//复制
#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
#include<fstream>
#include<iomanip>
using namespace std;
int main()
{int i_num[5] = { 1,2,3,4,5 };float f_num[5] = { 1.1,2.2,3.3,4.4,5.5 };int int_array[5];float f_array[5];ofstream out("myfile3");if (!out){cout << "scram\n";return 1;}out.write((const char *) &f_num, sizeof(f_num));out.write((const char *)&i_num, sizeof(i_num));out.close();ifstream in("myfile4");if (!in){cout << "no scram\n";return 1;}in.read((char*)&f_array,sizeof(f_array));in.read((char*)&int_array, sizeof(int_array));in.close();for (int i = 0; i < 5; i++){cout << f_array[i]<<" ";}cout << endl;for (int i = 0; i < 5; i++){cout << int_array[i]<<" ";}return 0;
}
#pragma warning(disable:4996)
#include<stdio.h> //c++中结构体与类 的区别是 类的继承私有的默认数据类型是私有的 而结构体是公有的 ,,类里面的变量叫做成员 结构体叫做数据  结构体还是一种数据结构的实现体 类是一个对象的实现体
#include<iostream>//ctrl+shift+f 选中所有相同的单词(代码)替换
#include<math.h>
#include<fstream>
#include<iomanip>
using namespace std;
//int main()
//{//  //ofstream out("myfile");
//  fstream out("myfile",ios::in|ios::out);
//  if (!out)
//  {//      cout << "cannot open myfile \n";
//      return 1;
//  }
//  out.seekp(5, ios::beg);
//  char c1 = 'X';
//  out.put(c1);
//  char c = 'Y';
//  out.seekp(10, ios::cur);
//  out.put(c);
//  out.close();
//
//  return 0;
//}
int main()
{ifstream in("myfile");if (!in){cout << "no scram";return 1;}char ch;in.seekg(5, ios::beg);if (in.get(ch)){cout << ch;}cout << endl;in.seekg(10, ios::cur);if (in.get(ch)){cout << ch;}cout << endl;in.seekg(3, ios::beg);for (int i = 0; !in.eof(); i++){in.get(ch);cout << ch<<":"<<i<<" ";}cout << endl;in.close();return 0;
}

c++i/o系统 纯。相关推荐

  1. ECSHOP系统纯静态网页的生成

    2019独角兽企业重金招聘Python工程师标准>>> ecshop是一个很不错的网店系统,现在很多公司都在用它,它本身优化也很好,不过因为是网店,很多东西都是动态的,所以,对优化来 ...

  2. java版停车系统(纯数据结构,无数据库)

    ** java版停车场管理系统 ** 项目要求:需要使用栈和队列两种数据结构.其中栈用于停车场和中转区,队列用于便道,对应的类名分别为:CarStack和CarQueue.CarStack为顺序栈,C ...

  3. 51 时间片系统 纯c语言,51单片C语言学习.doc

    51单片C语言学习 51单片机C语言学习第三课 [ 作者:明浩????转贴自:电子制作实验室????点击数:1067????更新时间:2004-10-2????文章录入:admin ]减小字体 增大字 ...

  4. 前端项目 - 博客系统(纯页面)

    预览效果 1. 实现博客列表页 导航栏 common.css blog_list.html blog_list.css 2. 实现博客正文页 blog_detail.html blog_detail. ...

  5. 不同系统下的shell的不同_方向盘越来越重:转向系统不同 原因也不同

    相信很多人都遇到过这样的经历,汽车时间开长了以后就会发现各种问题,其中就包括了我们的方向盘. 刚入手时方向盘转向很轻松,可一段时间后越用越沉,沉到似乎打不动的情况.为什么汽车方向盘会变得越来越重?这到 ...

  6. 在linux系统上怎么架设服务器吗,Linux下各种服务器的架设详解

    Linux下各种服务器的架设详解 本站整理   发布时间:2009-03-10 12:10:57   作者:jb51.net   我要评论 ########DNS########bind 篇##### ...

  7. PHP系统开发/Web文章博客

    PHP前后端交互 | web文章博客 前言 环境部署 一.登录 二.注册 三.主页 四.详情 五.编辑 六.删除 七.注销 八.发表 全部文件 总结 前言 一.项目需求: 做个基础的页面,文章博客we ...

  8. 华为 MA567x, 如何从电信系统切回华为系统

    本文档简述如何将MA5670系列路由器(光猫)由电信E8系统切回华为系统, 纯文字, 不配图 买了一个二手的MA5672, 该猫性能不错, 二手的价格也行, 可以替换掉原有光猫. 如果是电信系统的光猫 ...

  9. 记一次华为服务器装centos6.8系统

    记一次华为服务器装centos6.8系统 纯文本没截图,不要问我为什么,写给自己看的,二天忘了好看= =. [直接开车!!!] 纯文本没截图,不要问我为什么,写给自己看的,二天忘了好看= =. [直接 ...

最新文章

  1. 神曲背后的故事:算法工程师带你理性解构“蚂蚁呀嘿”
  2. ubuntu18.04升级cmake
  3. 【转】MS SQL Sever 远程安装导入数据演示(图)
  4. Linux下搭建iSCSI共享存储
  5. S2A哨兵数据的波段合成、镶嵌、TOA(大气表观反射率)和裁剪的操作
  6. 东方甄选推独立App自立门户;西湖大学『强化学习数学基础』教材书稿;经典书籍『深入浅出设计模式』Python版代码;前沿论文 | ShowMeAI资讯日报
  7. 64位微型计算机64指技术指标,\\\64位微型计算机\\\中的64,是指下列技术指标中的...
  8. 解决局域网共享文件时提示“没有权限访问,请与网络管理员联系请求访问权限“
  9. 阿里云服务器部署(保姆级)
  10. 华为服务器管理口在哪个位置,华为服务器默认管理口地址吗
  11. 访问控制列表之基本ACL、高级ACL 、 高级ACL之ICMP、高级ACL之telnet
  12. 小学六年级数学教案:圆柱与圆锥
  13. 团队RESTful 风格API规范
  14. python分时间段统计_Python Pandas:按日期分组并统计每个时段的新记录
  15. 利用计算机求解一个实际问题的步骤是,数学在计算机科学的应用.doc
  16. 头歌实训平台C语言答案
  17. 云计算介绍 TCP/IP协议以及配置
  18. Conflux人物志 | 杨哲:Sheldon Pro
  19. 燃情7月,ACMUG厦门、上海双城技术沙龙及MySQL/MariaDB创始人Monty中国行活动
  20. http协议及http协议和tcp协议的区别

热门文章

  1. 阿里2017校园招聘电话面试总结
  2. python里raise是什么意思_Python中raise与raise...from之间有何区别?
  3. 有什么好玩又能学到知识的编程游戏?
  4. Linux 文件系统的工作原理深度透析
  5. 源码阅读-Record
  6. CSS3新增的选择器有哪些?
  7. 洛谷 P1085 不高兴的津津 C语言
  8. LeetCode打卡:870.优势洗牌
  9. ubuntu 18共享文件夹不显示问题解决
  10. Spring AOP源码分析二