c++链表 异常 内部类 输出格式控制

C(控制台) F(文件)
---------------------------------------------
* I
	 cin			ifstream fin(文件名)

fin.close()
cin>> fin>>
cin.get(/*char&*/) fin.get(/*char&*/)
getline(cin/fin,str,'/*结束符*/')
read(内存地址,字节数)//此时注意长度
read()不会自动加'\0'
clear()恢复错误状态,ignore()清缓冲
peek() putback()把读出的字符放回缓冲区

----------------------------------------------
* O
	cout			ofstream fout(文件名)
cerr/clog fout.close()
<<
put()
write(内存地址,字节数)把内存中的数写到文件中
string str;
fin.read((char*)&str,sizeof(str));//结果不一定是想要的.
如果要读的是字符就用字符数组
fin.gcount()//最近读到多少个字符
fin.eof()//判断是否读到了文件末尾

控制台与文件的输入输出是完全一样的.
EOF end of file 代表-1
================================================
* 输出格式控制

只对格式化输出有效 <<
指定输出宽度:cout.width(int),一次性的,只对下一个输出有效
cout.fill('&')//在空白地方填充指定字符,不是一次性的
//例子
#include <iostream>
using namespace std;

class wf{
int w;
char ch;
public :
wf(int w, char c ):w(w),ch(c){}
friend ostream& operator<<(ostream& os, const wf& o){
os.width(o.w);
os.fill(o.ch);
return os;
}
};

int main()
{
cout << wf(10,'*') << 123 << endl;
cout << 123 << endl;
}


设置输出精度
cout.precision(8);
cout.setf()//控制输出格式

添加控制标志
cout.setf(ios::left|ios::hex)

常见输出控制标志:
ios:right,ios:dec(十进制),ios:oct(八进制),ios:hex,ios::showbase(带

前缀,如ox),ios::showpoint(总带小数点),ios::scientific(科学计数法)
ios::showpos(positive带符号),ios::uppercase(大写,把十六进制和科学计


数输出A~F时变大写)

cout.precision(2);
cout.setf(ios::fixed);//合起来用,设置小数后几位.

cout.unsetf(标志)//清除标志


#include <iostream>
using namespace std;

int main()
{
cout.width(10);
cout.fill('*');
cout.setf(ios::left);
cout << 123 << endl;
cout.setf(ios::showpos);
cout << 123 << endl;
cout.setf(ios::showpoint);
cout << 123.0 << endl;
cout.setf(ios::scientific|ios::uppercase);
cout << 1234.0 << endl;
cout.precision(2);
cout.unsetf(ios::scientific);
cout.setf(ios::fixed);
cout << 123.0 << endl;
cout.unsetf(ios::showpos);
cout.unsetf(ios::dec|ios::oct);
cout.setf(ios::hex);
cout.setf(ios::showbase);
cout << 123 << endl;
cout << "hello,world" << endl;
}


输出控制符
flush:清空缓冲
endl:insert a '\n' ,and clear out buffer
oct : set the output as oct
dec :十进制输出
hex: 十六进制输出
cout.setf(ios::left);//cout<<left与其等价
setw(宽度) ----> width
setfill(填充字符) ---> fill
setprecision(精度) ---> precision


注意:要用以上格式要包含头文件<iomanip>

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
cout << setw(10) << setfill('~') << left << 123 << endl;
cout << hex << showbase << uppercase << 123 << endl;
}

===============================================
ofstream fout(文件名,方式/*默认ios::out*/);
默认会清除文件中原内容
打开方式:ios::app(追加内容)
ios::binary:open file in binary mode;原样读写
ios::ate:start reading or writing at end of file
ios::in:ipen for reading
ios::trunc:truncate file to zero length if it exitsts
ios::out:open for writing

seekg(位置int);//读定位
seekp(位置int);//写定位
tellp()
tellg()//返回当前位置

//既可读也可写
fstream fio(文件名,ios::in|ios::out);
一般提倡读写分开.
+ 保存对象
A a(23);
fout.write((char*)&a,sizeof(a));
有一点如果要保存string对象时要先将其转换成c_str风格再转.
因为string里是一个指针,它的长度是4,如果保存的话会是一个地址,是毫无意

义的.
用法:fout.write((char*)strngObj.c_str(),strlen(strngObj));
-------------------------------
* 内部类

在一个作用域范围内定义的类叫做内部类.我们可以在一个函数里定义一个类

,也可以在一个类里定义一个内部类.
#include <iostream>
using namespace std;
class A /*全局类*/ {
public:
class B /*(成员)内部类*/ { };
//int b;//成员变量
};

class B /*可以叫B*/ { };

class D {
public :
class B { };
};

int main()
{
class C { };//(局部)内部类
//int c;//局部变量
C objc;
A obja;
A::B objab;//内部类的访问方法.
B objb;
D::B objdb;
}

内部类的作用:隐藏名字,避免冲突.可以通过其中统一的内部类名来统一各个类

的操作方法.其中最著名的就是迭代器.其实迭代器是类的内部类.
在c++里内部类与外部类毫不相干.
-------------------------------------------------
* 异常

如果不用异常程序各处会出现错误处理代码,使程序显的混乱,而异常处理将会

把错误集中处理,让程序结构清晰起来.
异常是不常见,但无法避免,可预料并作准备.
try {
if( 有异常情况 )
throw 数据;//在c++里什么都可以抛
}//监视是否有数据抛出.
catch/* 扑获异常 */( 类型 变量名 ) {

/* 对异常处理code */
}//catch是用来集中处理错误信息的
catch( 类型 变量名 ) {

/* 对异常处理code */
}//可以有若干个catch,对不同的异常进行处理.

c++的异常处理就像小两口打架,想抛什么就抛什么.
//例子,异常处理
#include <iostream>
#include <fstream>
using namespace std;

int main(int argc, char* argv[])
{
try {
ifstream fin(argv[1]);
if(!fin)
throw 100;
char buf[1000];
fin.read(buf,1000);
if(!fin)
throw 100.0;
cout.write( buf, 1000);
fin.close();

}catch(double e) {
cout << "double:" << e << endl;
}catch(long e) {
cout << "long:" << e << endl;
}catch(...)/*接收所有的异常*/ {
cout << "Exception Error!" << endl;
}
cout << "What a good day!" << endl;

}


exception类有一个成员函数what()用来返回描述异常的字符串e.what();
在一个函数里如果有没有被捕获的异常会被抛到调用它的地方.
最终会传到main函数里面.所以我们在main里写上下面语句块:
try { } catch(...) { } 这样就能处理所有的异常.
抛出子类型对象异常,可以用父类对象来进行捕获.当一起进行捕获,但要注意先

后顺序,一般是先catch子类再catch父类对象.
catch( 类型 变量 ) {
throw;
}//处理不了,重新抛出该异常.一般不这么做,偶尔做一做
其中的类型可以是自定义类型,同样可以向外抛.
====================================================

* 重要数据结构与算法

+ 链表
结构中也可以写构造函数,结构与类的区别最主要的区别就是结构中默认的成员

是public型的,而类中成员默认是private型的.其他的大致相同.
基本类型()的值是0
T(),T是基本类型时值是0,T是类时T()会是一个无名对象.
当然编译器有可能会优化程序.

//链表示例
#include <iostream>
using namespace std;
typedef int T;

int main()
{
struct Node {
T data;
Node* next;
Node(const T& d) : data(d),next(NULL){ }
};
Node* header = NULL;
cout << "Please input some integers : " << endl;
do{
T data;
cin >> data;
//cout << (int)data << ' ';
Node* p = new Node(data);
p->next = header;
header = p;
}while(cin.get()!='\n');
Node* p = header;
while(p){
cout << p->data << ' ';
p = p->next;
}
cout << endl;
p = header;
while(p){
Node* q = p->next;
delete p;
p = q;
}
}


//链表类示例程序
//功能:支持增,删,改,查
#include <iostream>
using namespace std;
typedef int T;

class List {
struct Node {
T data;
Node* next;
Node( const T& t=T()) : data(t),next(NULL){ }
}; //end of struct Node

Node* head ;

public:
List() : head(NULL){ }
void insertFirst( const T& t ){
Node* p = new Node(t);
p->next = head;
head = p;
}
void travel(){
Node* p = head;
while(p){
cout << p->data << ' ' ;
p = p->next;
}
cout << endl;
}
void free(){
while(head){
Node* q = head->next;
delete head;
head = q;
}
}
int size(){
Node* p = head;
int cnt=0;
while(p){
p = p->next;
cnt ++;
}
return cnt;
}
~List(){
free();
cout << "~List() called" << endl;
}
int find( const T& t ){
Node* p = head;
int cnt = 0;
while(p){
if(p->data==t) return cnt;
p = p->next;
cnt++;
}
return -1;
}
T getHead(){
if(!head) throw "Exception: No head";
return head->data;
}
T getTail(){
if(!head) throw "Exception: No tail";
Node* p = head;
while(p->next)
p = p->next;
return p->data;
}
T get( int index ){
Node* p = getPointer(index);
return p->data;
}
bool erase( int index ){
if( 0== index ){
Node* p = head;
head = head->next;
delete p;
return true;
}
else{
Node* pre = getPointer(index-1);
Node* cur = pre->next;
pre->next = cur->next;
delete cur;
return true;
}
return false;
}
bool update(const T& old, const T& nw){
int index=find(old);
if(index<0)
return false;
Node* p = getPointer(index);
p->data = nw;
return true;
}
private :
Node* getPointer(int index){
if(index<0 || index>=size()){
throw "Exception:index out of bound" ;
}
Node* p = head;
for( int i=0; i<index; i++)
p = p->next;
return p;
}
};//end of class List
int main()
{
List list;
list.insertFirst(1);
list.insertFirst(2);
list.insertFirst(3);
list.insertFirst(4);
list.insertFirst(5);
list.travel();
cout << "list.size():" << list.size() << endl;
cout << "list.find(2):" << list.find(2) << endl;
cout << "list.find(9):" << list.find(9) << endl;
cout << "getHead:" << list.getHead() << endl;
cout << "getTail:" << list.getTail() << endl;
cout << "get(3):" << list.get(3) << endl;
try{
cout << "get(9):" << list.get(9) << endl;
}
catch(...){
cout << "Exception" << endl;
}
//cout << "get(5):" << list.get(5) << endl;//ERROR
cout << "------------------" << endl;
list.erase(0);
list.travel();
try{
list.erase(2);
}
catch(...){cout << "Exception" << endl;}
list.travel();
list.update(1,100);
list.travel();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值