c++:对文件的流式操作(ofstream,ifstream,fstream)(ostringstream,istringstream,stringstream)

目录

 

ofstream,ifstream,fstream

操作函数整理

代码演示&原理解释

文件定位问题:

ostringstream,istringstream,stringstream

代码演示

istringstream

ostringstream

stringstream


对文件和流的理解:

      打开,删除,移动文件,这些都是文件操作,文件和流是两个概念,文件更多是指存储到磁盘上的数据集,
它有具体的路径和名称,可以直接看见。

      流不仅仅是指打开的文件,还可以是一串网络数据,内存数据,流的基本操作就是读取和写入,定位。将数据在某些数据结构中相互转换,

ofstream,ifstream,fstream

操作函数整理

C++ 通过以下几个类支持文件的输入输出:

  • ofstream: 写操作(输出)的文件类
  • ifstream: 读操作(输入)的文件类
  • fstream: 可同时读写操作的文件类 

对要操作的文件第一件事肯定是打开它,并使用一个流对象去描述它,对流对象的操作实际就是对该文件的操作。

头文件:fstream

使用流对象打开一个文件,使用成员函数:
void open (const char * filename, openmode mode,int access);
filename:代表文件名/路径的字符串
mode:打开方式
access:打开文件的属性 0普通文件,1只读文件,2隐含文件,4系统文件

常见打开方式:
ios::in     :以输入(读)方式打开文件
ios::out    :以输出(写)方式打开文件
ios::binary :以二进制方式打开文件
ios::trunc  :如果文件已存在则先删除文件

所有操作符可以使用'|'进行组合使用
以二进制写方式打开文件:
ofstream file;
file.open("test.bin",ios::binary);

ofstream, ifstream 和 fstream所有这些类的成员函数open
都包含了一个默认打开文件的方式,这三个类的默认方式各不相同
如果open时没有指定打开方式会使用默认值
ofstream: ios::out | ios::trunc
ifstream: ios::in
fstream:  ios::in | ios::out

 其实也简单一点打开文件

ofstream fout("文件名");
ifstream fin("文件名");
fout fin为行惯性命令的类对象
通过:bool is_open() 函数判断文件是否被顺利打开
列如:if( testfile.is_open() )
关闭文件:
当文件读写完成时,必须关闭文件使文件变的重新可访问
void close();
调用函数后,原先的流对象就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程访问了。

stream中有两个重要的运算符:

1:插入器(<<)
  向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,
       所以,cout<<"test";就表示把字符串"test"输出到标准输出流。

2:析取器(>>)
  从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘
       所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据

代码演示&原理解释

类ofstream, ifstream 和fstream 是分别从ostream, istream 和iostream 中引申而来的。这就是为什么 fstream 的对象可以使用其父类的成员来访问数据。

ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲简单理解为内存空间;

但是实际上还有一个中间层streambuf类型的缓存(buffer),作为流与物理文件的媒介

字符不是直接从流进入文件,而是先被存在buffer中,当缓冲被刷新(flush)的时候,里面所有的数据才会被写入物理文件

//写
#include
#incllude
using namespace std;

int main()
{
    ofstream testfile("test.txt");
    if (testfile.is_open())
    {
        testfile << "hello\n";
        testlefile.close();
    }
    return 0;
}
//读
#include 
#include 
#include 
using namespace std;
int main ()
{
    char buffer[256];
    ifstream file("example.txt");
    if (!file.is_open())
    {
        cout << "Error opening file"; 
        return 0;
    }
    while (!file.eof())
    {
       file.getline(buffer,100);
        cout<

 

文件定位问题:

c++在IO系统管理文件时有两个文件相关的指针,读指针和写指针,

读指针是输入操作在文件中的位置,写指针是写操作的执行位置,每次执行输入输出,指针位置自动够改变

分贝对应成员函数seekg()设置读位置, seekp()设置写位置

istream &seekg(streamoff offset,seek_dir origin);
ostream &seekp(streamoff offset,seek_dir origin);

streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值
seek_dir 表示移动的基准位置,是一个有以下值的枚举:
   ios::beg: 文件开头 
   ios::cur: 文件当前位置 
   ios::end: 文件结尾 
这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同

file1.seekg(1234,ios::cur);//把文件的读指针从当前位置向后移1234个字节
file2.seekp(1234,ios::beg);//把文件的写指针从文件开头向后移1234个字节

ostringstream,istringstream,stringstream

C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含sstream头文件。

istringstream类用于执行C++风格的串流的输入操作。

ostringstream类用于执行C风格的串流的输出操作。 

stringstream类同时可以支持C风格,c++风格的串流的输入输出操作。

一般情况下stringstream使用最多

c++:对文件的流式操作(ofstream,ifstream,fstream)(ostringstream,istringstream,stringstream)_第1张图片

代码演示

istringstream

#include
#include  
using namespace std;
int main(){
	string test = "-123 9.87 welcome to, 989, test!";
	istringstream iss;//istringstream提供读 string 的功能
	iss.str(test);//将 string 类型的 test 复制给 iss,返回 void 
	string s;
	cout << "按照空格读取字符串:" << endl;
	while (iss >> s){
		cout << s << endl;//按空格读取string
	}
	cout << "*********************" << endl;
 
	istringstream strm(test); 
	//创建存储 test 的副本的 stringstream 对象
	int i;
	float f;
	char c;
	char buff[1024];
 
	strm >> i;
	cout <<"读取int类型:"<< i << endl;
	strm >> f;
	cout <<"读取float类型:"<> c;
	cout <<"读取char类型:"<< c << endl;
	strm >> buff;
	cout <<"读取buffer类型:"<< buff << endl;
	strm.ignore(100, ',');
	int j;
	strm >> j;
	cout <<"忽略‘,’读取int类型:"<< j << endl;
 
	system("pause");
	return 0;
}

代码来源:https://blog.csdn.net/Sophia1224/article/details/53054698

总结:

  1. istringstream类中,构造字符串流时,空格会成为字符串参数的内部分界
  2. istringstream类可以用作string与各种类型的转换途径
  3. ignore()参数:需要读取最大长度,需要忽略的字符

ostringstream

int main(){
	ostringstream out;
	out.put('t');//插入字符
	out.put('e');
	out << "st";
	string res = out.str();//提取字符串;
	cout << res << endl;
	system("pause");
	return 0;
}
//输出:test
//之后写入的部分会在原基础上增加

stringstream

主要分为两个作用:

1:整行读取时可以按空格划分

        string s = "12 34 56";
        ss.clear();
        ss.str(s);
        while (1)
        {
            int a;
 
            ss >> a;
            //自动按照空格划分(读指针会自动改变)
            if(ss.fail())
                break;
            //读完结束
            cout << a << endl;
        }
//输出:12 34 56
//在线OJ时遇见不定长的数据,stringstream是很方便的输入方式
int main()
{
	string str;
	getline(cin,str);
	stringstream ss(str);
	int tmp = 0;
	vector v;
	while (ss>>tmp)
	{
		v.push_back(tmp);
	}

	return 0;
}

2:简化类型转换

#include 
#include 
#include 
using namespace std;
 
int main()
{
	stringstream ss;
	int first = 0;
 
	ss << "456";  // 插入字符串
	ss >> first;  //转换成int
	cout << first << endl;
 
	ss.clear();  //在进行多次转换前, 必须清除ss
    string s;
    int a = 123;
    ss<>s;
	cout << s << endl;
 
	return 0;
}

类型转化自动实现更加安全可靠不会溢出

更多转换实现:https://blog.csdn.net/sunshineacm/article/details/78068987

你可能感兴趣的:(c++)