[C++_12]IO_2

16.3 字符串IO

istringstream / ostringstream : stringstream


16.3.1 istringstream类

从流中提取数据,支持 >> 操作,这里字符串可以包括多个单词,单词之间使用空格分开
初始化:使用字符串进行初始化 构造函数:istringstream::istringstream(string str);
使用:我们可以使用分解点获取不同的数据,完成 字符串 到 其他类型 的转换

16.3.2 ostringstream类

把其他类型的数据写入流(往流中写入数据),支持<<操作
初始化:使用字符串进行初始化,构造函数:ostringstream::ostringstream(string str);

16.3.3 stringstream类

是对istringstream和ostringstream类的综合,支持<<, >>操作符,可以进行字符串到其它类型的快速转换
初始化:使用字符串进行初始化 构造函数:stringstream::stringstream(string str);
作用:1、stringstream通常是用来做数据转换的
          2、将文件的所有数据一次性读入内存

注意:stringstream sst 成员函数

         sst.str("") 常用来初始化/覆盖 字符串或清空   << 追加字符串

         sst.clear() 清除错误状态

#include<iostream>
#include<string>
#include<sstream>
using namespace std;

int main()
{
  string str1,str2,str3;
  cout << "请输入一行字符:" << endl;
  getline(cin,str1);
  istringstream is(str1);
  is >> str2;
  is >> str3;
  cout << "str2=" << str2 << endl << "str3=" << str3 << endl;
  
  ostringstream os;
  os << str2 << str3;
  cout << "str2+ str3 = " << os.str()<< endl;
  cout << os.str()[1];
  
  return 0;
}

输出结果:

关于sstringstream内存消耗问题参见:

http://www.cnblogs.com/gamesky/archive/2013/01/09/2852356.html

16.4 文件IO


ofstream是从内存到硬盘,ifstream是从硬盘到内存


16.4.1打开文件

  在fstream类中,有一个成员函数open(),就是用来打开文件的,或者使用构造函数,声明如下:

void open(const char* filename,int mode,int access);

void fstream(const char* filename,int mode,int access);


参数:filename:   要打开的文件名

          mode:   要打开文件的方式

          access:    打开文件的属性


打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:(可或)
ios::app:   以追加的方式打开文件
ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in:    文件以输入方式打开(文件数据输入到内存)
ios::out:   文件以输出方式打开(内存数据输出到文件)
ios::nocreate: 不建立文件,所以文件不存在时打开失败
ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc:  如果文件存在,把文件长度设为0


打开文件的属性取值是:(可加)

0:普通文件,打开访问
1:只读文件
2:隐含文件

4:系统文件


16.4.2 关闭文件

  打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。


16.4.3 读写文件

  读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式
1、文本文件的读写

  文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。

 

2、二进制文件的读写
put()

ofstream &put(char ch) 如file1.put('c');就是向流写一个字符'c'。


get()

    ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch,如果到文件尾,返回空字符。

    int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,

    ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。


读写数据块(read/write)
read(unsigned char *buf,int num);
write(const unsigned char *buf,int num);

 read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。

注意:使用string时格式应为:read(string.c_str(),string.size()),而不是直接使用string和sizeof(string),string是一个类的对象,里面封装了指针。


16.4.4 检测EOF

  成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();

例:  if(in.eof()) ShowMessage("已经到达文件尾!");


16.4.5 文件定位

  和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置(注意:在fstream中,读指针与写指针始终相同)。它们最通用的形式如下:
    istream &seekg(streamoff offset,seek_dir origin);-->tellg() 返回读指针所在位置

    ostream &seekp(streamoff offset,seek_dir origin);-->tellp() 返回写指针所在位置

 streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
ios::beg:  文件开头
ios::cur:  文件当前位置
ios::end:  文件结尾

#include<iostream>
#include<string>
#include<fstream>

using namespace std;

int main()
{
  string path = "../Desktop/write.txt";
  ifstream fin("./conIO.cpp");
  ofstream fou(path.c_str());//此处形参为 const char*(C风格字符串)
  if(!fin) cout << "write.txt打开失败!" << endl;
  if(!fou) cout << "charIO.cpp打开失败!" << endl;
  char ch;
  while(fin.get(ch))//用while(fin>>ch)会跳过所有空白字符
  {
	cout << ch;
	fou << ch;
  }//while(fin) {fin.get(ch);fout<<ch;} 这样复制最后会多一个字符
  fin.clear();
  fin.close();
  fou.close();
  return 0;
}
输出结果:


二进制加密程序:

#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;

void encode(char *ch,int cnt)
{
  int i = 0;
  for(;i < cnt ; i++)
	++ch[i];
}

void decode(char *ch ,int cnt)
{
  int i = 0;
  for(;i < cnt ; i++)
  {
	--ch[i];
  }
}
int main(int argc,char *argv[])
{
  
  if(argc != 3||(!strcmp(argv[1],"-e")&&!strcmp(argv[1],"-d"))) 
  {
	cout << argv[0] << " -e/-d filename" << endl;
	return -1;
  }
  //生成输出文件
  string str0 = argv[2];
  string str1 = strcmp(argv[1],"-e")?"decode":"encode";//注意:strcmp返回值为1/0/-1
  string filename =  str1+"_"+str0 ;
  fstream fin(filename.c_str(),ios::out);//(内存-->文件)
  //只有ios::out才可以自动生成文件,ios::out|ios::in是不可以的
  fstream fout(argv[2],ios::in|ios::binary); //(文件-->内存)
  if(!fin)
  {
	cout << "打开" << filename << "失败!" << endl;
	return 1;
  }
  if(!fout)
  {
	cout << "打开" <<argv[2] << "失败!" << endl;
	return 2;
  }
  void (*p)(char*,int) = strcmp(argv[1],"-e")?decode:encode;//定义函数指针
  bool temp[100],state;
  int bytes,pos1,pos2;
  while(state)
  {
	
	fout.read((char*)temp,sizeof(temp));
	if(!fout)                 //注意当read读取不足sizeof(temp)时,fout状态置false
	{
	  fout.clear();
	  state = 0;
	  
	}
	bytes = fout.gcount();
	p((char*)temp,bytes); 
	fin.write((char*)temp,bytes);
  }
  fout.clear();
  fout.close();
  fin.close();  
  return 0;  
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值