C++的I/O(vc版)(五)

C++的I/O(vc版)(四) 下面进行我们的第二大类,流缓冲类。stream并不负责写或者读,毕竟如它原本的目的一样:负责格式化,存储格式化信息;当然我们还用它存储状态信息等等。stream把它的读写工作转交给stream buffer,即缓冲区类。 缓冲区类主要是围绕着位置展开操作,下面先介绍一个与位置有关的类: /*fpos:它可以存储还原任何流中的任意文件的位置指示器所需的所有信息 * 对象的类 fpos 阅读详情

 具体的缓冲类有filebuf,stringbuf,由于filebuf的大部分工作都转交给了C流,不好分析,所以重点分析的还是stringbuf。

 对于stringstream,我们最常用的语句就是:

string s="1.2 5.6 7 7 ";
istringstream is(s);
float f;
 is >> f;

上述语句,给出了stringbuf的基本形式:以string初始化;

首先,假设我们已经都了解了stringstream的基本用法:ostringstream:向string中写数据;istringstream:从string中读取数据;

首先我们来说明一下stringbuf中的六个指针:其实在basic_stingbuf<>中,input和output共用缓冲区,且read操作的字符永远包含在write操作的字符之内,即先write后read:

这六个指针明确了,大部分问题就解决了。

首先看一下数据成员:

	typedef basic_stringbuf<_Elem,_Traits,_Alloc> _Myt;
	typedef _Alloc allocator_type;
	typedef basic_streambuf<_Elem,_Traits> _Mysb;
	typedef basic_string<_Elem,_Traits,_Alloc> _Mystr;
	typedef typename _Traits::int_type int_type;
	typedef typename _Traits::pos_type pos_type;
	typedef typename _Traits::off_type off_type;
	_Elem* _seekhigh;
	_Strstate _mystate;//stream state
	allocator_type _alloc;

对于流缓冲类需要知道一些状态信息,来决定basic_stringbuf<>的行为,具体的状态信息如下:

	enum
	{//constants for bits in stream state
		_Allocated=1,//set if character array storage has been allocated
		_Constant=2,//set if character array nonmutable
		_Noread=4,//set if character array cannot be read
		_Append=8,//set if all writes are qppends
		_Atend=16};//set if initial writes are appends


	typedef int _Strstate;
 _Strstate _Getstate(ios_base::openmode _mode)
    {//convert open mode to stream state bits
        _Strstate _state=(_Strstate)0;
        if(!(_mode &ios_base::in))
            _state|=_Noread;
        if(!(_mode&ios_base::out))
            _state|=_Constant;
        if(_mdoe&ios_base::app)
            _state|=_Append;
        if(_mode&ios_base::ate)
            _state|=_Atend;
        return (_state);
    }

其中_Getstate()用来将openmode的信息,转化成自己所需要的状态信息。

初始化过程:

	explicit basic_stringbuf(ios_base::openmode _mode=ios_base::in|ios_base::out)
	{
		_Init(0,0,_Getstate(_mode));
	}
	explicit basic_stringbuf(const _Mystr& _str,ios_base::openmode _mode=ios_base::in|ios_base::out)
	{
		_Init(_str.c_str(),_str.size(),_Getstate(_mode));
	}

	void _Init(const _Elem* _ptr,size_t _count,_Strstate _state)
	{//initialize buffer to[_ptr,_ptr+_count),set state
		_seekhigh=0;
		_mystate=_state;
		if(_count!=0 &&(_mystate&(_Noread|_Constant))!=(_Noread|_Constant)){
			//buffer that be read or writer
			_Elem* _pnew=_alloc.allocate(_count);
			_Traits::copy(_pnew,_ptr,_count);
			_seekhigh=_pnew+_count;

			if(!(_mystate &_Noread))
				_Mysb::setg(_pnew,_pnew,_pnew+_count);//set up read buffer
			if(!(_mystate &_Constant)){
				//set up writer buffer,是追加模式还是重置模式

                                 _Mysb::setp(_pnew,(_mystate&_Atend)?_pnew+_count:_pnew,_pnew+_count);
				if(_Mysb::gptr()==0)
					_Mysb::setg(_pnew,0,_pnew);
			}
			_mystate|=_Allocate;
		}
	}

其中的主要工作转交给了_init函数,首先复制ptr指向的数组的内容,然后此函数根据状态信息初始化六个指针;

然后是stringstream中特有的两个函数str()和str(newstr),str()用来返回流中的内容,如果流既可以读也可以写,返回所有而不只是input缓冲区中的,如果这可以读,则返回input区中的内容,具体实现参见下述代码,而str(newstr)用来将流中的数据重置为newstr;

	_Mystr str() const
	{//return string copy of character array
		if(!(_mystate&_Constant)&&_Mysb::pptr()!=0)
		{//writable,make string from write buffer
			_Mystr _str(_Mysb::pbase(),(_seekhigh<_Mysb::pptr()
				?_Mysb::pptr() :_seekhigh)-_Mysb::pbase());
			return (_str);
		}else if(!(_mystate& _Noread) &&_Myssb::gptr()!=0){
			//readable.make string from read buffer
			_Mystr _str(_Mysb::eback(),_Mysb::egptr()-_Mysb::eback());
			return (_str);
		}else{
			_Mystr _nul;
			return (_nul);
		}
	}
	void str(const _Mystr& _newstr)
	{
		_Tidy();
		_Init(_newstr.c_str(),_newstr.size(),_mystate);
	}

下面进入正题,正如我们上一篇文章中讨论的那样,一个流的具体实现的关键环节在于那几个关键的虚函数,overflow,underflow,uflow,pbackfail,seekpos,seekoff:

	virtual int_type overflow(int_type _meta=_Traits::eof())
	{
		if(_mystate &_Append &&_Mysb::pptr()!=0 &&_Mysb::pptr()<_seekhigh)
			_Mysb::setp(_Mysb::pbase(),_seekhigh,_mystate);

		if(_Traits::eq_int_type(_Traits::eof(),_meta))
			return (_Traits::not_eof(_meta));//EOF return success code
		else if(_Mysb::pptr()!=0 &&_Mysb::pptr()<_Mysb::epptr()){
			*_Mysb::_Pninc=_Traits::to_char_type(_meta);
			return (_meta);
		}
		else if(_mystate &_Constant)
			return (_Traits::eof());//array cannot write,fail
		else{//grow buffer and store
			size_t _oldsize=_mysb::pptr()==0?0:_Mysb::epptr()-_Mysb::eback();
			size_t _newsize=_oldsize;
			size_t _inc=_newsize/2<_MINSIZE?_MINSIZE:_newsize/2;//grow by 0.5 _MINSIZE=32
			while(0<_inc &&INT_MAX-_inc<_newsize)
				_inc/=2;
			if(_inc==0)
				return(_Traits::eof());//buffer cannot grow,增长的极限
			_newsize+=_inc;
			//上述代码确定增长的大小
			//分配空间
			_Elem* _newptr=_alloc.allocate(_newsize);
			_Elem* _oldptr=_Mysb::eback();
			//先将原来的数据复制进新的缓冲区
			if(0<_oldsize)
				_Traits::copy(_newptr,_oldptr,_oldsize);
			//如果原来的缓冲区大小为0,根据状态信息设置指针位置
			if(_oldsize==0){//first growth,set up pointer
				_seekhigh=_newptr;
				_Mysb::setp(_newptr,_newptr+_newsize);
				if(_mystate &_Noread)
					_Mysb::setg(_newptr,0,_newptr);
				else
					_Mysb::setg(_newptr,_newptr,_newptr+1);
			}
			else{//一般情况下的指针位置设置
				_seekhigh=_newptr+(_seekhigh-_oldptr);
				_Mysb::setp(_newptr+(_Mysb::pbase()-_oldptr),_newptr + (_Mysb::pptr() - _oldptr),_newptr + _newsize);
				if(_mystate &_Noread)
					_Mysb::setg(_newptr,0,_newptr);
				else
					_Mysb::setg(_newptr,_newptr+(_Mysb::gptr()-_oldptr),_Mysb::pptr()+1);
			}
			//如果我们以前的内存是通过分配器分的,那么就再通过它删除,同时,这次的内存一定是分配器分的,所以
			//设置状态
			if(_mystate &_Allocated)
				_alloc.deallocate(_oldptr,_oldsize);
			_mystate|=_Allocated;
			//写入字符
			*_Mysb::_Pninc()=_Traits::to_char_type(_meta);
			return(_meta);
		}
	}

上述代码给出了overflow的实现,也就是当write缓冲区已满,我们应该怎么做?这里的实现是使缓冲区增长为原来的1.5倍。具体的代码

对于underflow和uflow:

	virtual int_type underflow()
	{
		//不能读取得情况下,读取失败
		if(_Mysb::gptr()==0)
			return (_Traits::eof());
		//正常情况下,正常读取
		else if (_Mysb::gptr()<_Mysb::egptr())
			return(_Traits::to_int_type(*_Mysb::gptr()));
		//不能读取情况有下述几种情况:
		else if(_mystate & _Noread || _Mysb::pptr() == 0|| _Mysb::pptr() <= _Mysb::gptr()
			&& _seekhigh <= _Mysb::gptr())
			return (_Traits::eof());	// can't read, fail
		else{//extend read buffer into written area
			//这才是underflow的菜,如果发现read区的结尾指针小于write区,那么把结尾指针移动write区的pptr()
			if(_seekhigh<_Mysb::pptr())
				_seekhigh=_Mysb::pptr();
			_Mysb::setg(_Mysb::eback(),_Mysb::gptr(),_seekhigh);
			return (_Traits::to_int_type(*_Mysb::gptr()));
		}
	}

下面是pbackfail:

	virtual int_type pbackfail(int_type _meta=_Traits::eof())
	{//put an element back to stream
		if (_Mysb::gptr() == 0|| _Mysb::gptr() <= _Mysb::eback()|| !_Traits::eq_int_type(_Traits::eof(), _meta)
			&& !_Traits::eq(_Traits::to_char_type(_meta), _Mysb::gptr()[-1])&& _mystate & _Constant)
			return (_Traits::eof());//fail
		else{
			_Mysb::gbump(-1);
			if(!_Traits::eq_int_type(_Traits::eof(),_meta))
				*_Mysb::gptr()=_Traits::to_char_type(_mate);
			return (_Traits::not_eof(_meta));
		}
	}

最后是seekoff和seekpos,由于在stringbuf中两者的相似性,下面仅附seekoff的代码:

	virtual pos_type seekoff(off_type _off,ios_base::seekdir _way,ios_base::openmode _mode=ios_base::in | ios_base::out)
	{
		//首先更新_seekhigh
		if(_Mysb::pptr()!=0 &&_seekhigh<_Mysb::pptr())
			_seekhigh=_Mysb::pptr();//update seekhigh
		//调整read区
		if(_mode&ios_base::in && _Mysb::gptr()!=0){//position within read buffer
			if(_way==ios_base::end)
				_off+=(off_type)(_Mysb::gptr()-_Mysb::eback());
			else if (_way == ios_base::cur
				&& (_mode & ios_base::out) == 0)
				_off += (off_type)(_Mysb::gptr() - _Mysb::eback());
			else if (_way != ios_base::beg)
				_off = _BADOFF;

			if (0 <= _off && _off <= _seekhigh - _Mysb::eback())
				{	// change read position
				_Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _off));
				if (_mode & ios_base::out && _Mysb::pptr() != 0)
					_Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
						_Mysb::epptr());	// change write position to match
				}
			else
				_off = _BADOFF;
			}
		//调整write区
		else if (_mode & ios_base::out && _Mysb::pptr() != 0)
			{	// position within write buffer
			if (_way == ios_base::end)
				_off += (off_type)(_seekhigh - _Mysb::eback());
			else if (_way == ios_base::cur)
				_off += (off_type)(_Mysb::pptr() - _Mysb::eback());
			else if (_way != ios_base::beg)
				_off = _BADOFF;

			if (0 <= _off && _off <= _seekhigh - _Mysb::eback())
				_Mysb::pbump((int)(_Mysb::eback()
					- _Mysb::pptr() + _off));	// change write position
			else
				_off = _BADOFF;
			}
		else if (_off != 0)
			_off = _BADOFF;	// neither read nor write buffer selected, fail
		return (pos_type(_off));
	}
	//seekpos 就不写了

至此,basic_stringbuf<>的关键部分就完成了。

对于针对是istringstream还是ostreamstring所用的缓冲区,对basic_stringbuf的openmode传递不同的参数即可。






c++builder调用VC的dll以及VC调用c++builder的dll 解析__cdecl,__fastcall, __stdcall 的不同:在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式。 比如说__cdecl,它是标准的c方法的堆栈调用方式,就是在函数调用时的参数压入堆栈是与函数的声明顺序相反的,其它两个可以看MSDN,不过这个对我们编程没有太大的作用 ------------------------------------------ 阅读详情

相关推荐

使你的C/C++代码支持Unicode

使你的C/C++代码支持Unicode

jhfyuf的博客 4680

C++ 头文件系列(streambuf)

1. 简介 该头文件定义了basic_streambuf模版,从字面上看是作为流缓冲区之用。 2. basic_streambuf模版 The class template basic_stream< charT, traits > serves as an abstract base class for deriving various stream buffers whose o...

weixin_30256901的博客 706

VC/C++实现TXT到DAT文件转换的源代码

本文还有配套的精品资源,点击获取 简介:在IT行业中,文件格式转换是一个常见任务,特别是在文本数据处理方面。本文详细介绍了如何通过VC/C++编程语言实现从TXT文本文件到DAT数据文件的转换。此转换流程包括读取TXT文件内容、数据预处理、创建并写入DAT文件等步骤。在VC/MFC环境中,还可以利用MFC库简化文件操作,并创建图形用户界面。 1. 文件格式转换基础...

weixin_35649491的博客 1314

C++中的文件file和流缓冲streambuf操作

1.引入头文件fstream #include &lt;fstream&gt; fstream头文件定义了用于文件输入的类ifstream和文件输出的类ofstream 参考文档 http://www.cplusplus.com/reference/fstream/ ofstream: 写操作(输出)的文件类 (由ostream引申而来)  ifstream: 读操作(输入)的文件类(由istr...

halazi100 7102

高效处理大文件的重叠I/O VC++源代码解析

OVERLAPPED结构体是Windows平台上用于处理异步I/O请求的一种数据结构。它允许应用程序在文件操作(如读取和写入)进行的同时,继续执行其他任务。在本章节中,我们详细讨论了OVERLAPPED结构体的介绍、在重叠I/O中的应用,以及处理超大文件和错误管理的高级技巧。在Windows平台开发中,合理利用OVERLAPPED结构体能够有效提升应用程序的性能和效率。在接下来的章节中,我们将继续探讨如何在VC++中实现重叠I/O,以及WinAPI中CreateFileReadFile。

weixin_33193177的博客 769

LVGL v9的lv_scale控件实战:5分钟打造动态仪表盘(附完整代码)

本文详细介绍了LVGL v9中lv_scale控件的实战应用,通过5个关键步骤快速打造动态仪表盘。文章涵盖核心特性解析、代码实现、样式定制及性能优化,适用于工业HMI、智能家居等场景,并附完整代码示例。

gin88的博客 262

2.24-2.28的fsop

2.24-2.28的fsop: 2.23的fsop对这个版本段的glibc是无效的,多加的保护机制如下: 新版本(libc2.24以上)的防御机制会检查vtable的合法性,不能再像之前那样改vatable为堆地址,但是_IO_str_jumps是一个符合条件的 vtable,改 vtable为 _IO_str_jumps即可绕过检查。 _IO_str_jumps是一个方向,使用比较简单,这里就只讲这个方向了。 利用: 新版本(libc2.24以上)的防御机制会检查vtable的合法性,不能.

qq_51474381的博客 622

芯片封装、功率密度提升及热管理系统优化三个维度分析高功率芯片散热技术挑战

本文探讨高功率芯片散热技术挑战与创新。随着新能源汽车MOSFET用量增至400颗/车,文章聚焦封装技术创新(双面散热、集成模块)、功率密度提升(SGT-MOSFET优化)和热管理系统协同优化三大方向。通过热仿真案例(如CPO散热优化)展示温升改善方案,强调需协同器件级设计、系统级仿真与先进封装技术(混合键合/玻璃基板)来解决高密度互连与散热矛盾,为功率密度跃升提供技术支撑。

莱歌数字的博客 1473

为什么要引入filebuf这个对象呢?

ifstream::rdbuf可以返回与此文件流相关联的filebuf对象。用这个对象可以判断打开,输入输出,可是这些事ifstream自己都可以作了,为什么要引入这个对象呢?

3655

2023最新版kali安装教程

2023最新版kali安装教程 打开kali官网(https://www.kali.org/),下载kali镜像

qq_46346209的博客 2万+

ABAP_自定义屏幕07—下拉列表框

ABAP_自定义屏幕07—下拉列表框 完成以下:页面中有下拉列表框,下拉框value=系统表SCRR的值 1、实现方法A-常用 1.1 在主程序定义字段 TYPES:BEGIN OF type_carrid, carrid LIKE scarr-carrid,"航线代码 carrname LIKE scarr-carrname,"航向名称 END OF type_carrid. DATA g_it_carrid TYPE STANDARD TABLE OF type_carrid

f346348157的博客 3871

Linux C\C++方式下的文件I/O编程

在旧头文件里的fstream.h,如果使用ifstreamfile的默认参数声明一个输入文件流,当这个要读的file文件不存在时,会自动创建一个空文件,从而给判断文件是否存在造成了很多麻烦。因为C++兼容C,所以C中的输入输出函数依然可以在C++中使用,但是很显然,直接把C的那套输入输出搬到C++中肯定无法满足C++的需求,更重要的一点是,C中的输入输出有类型要求,只支持基本类型,因此C++设计了易于使用的并且多种输入输出流接口统一的I/O类库,并且支持多种格式化操作,还可以自定义格式化操作。

夏天又到了的专栏 3182

在Windows11下安装完Ubuntu20.04双系统后配置环境的过程

在Windows11下安装完Ubuntu20.04双系统后配置环境的过程 1.NVIDIA驱动检测及安装 2.Anaconda的安装 3.安装cuda、cudnn、pytorch 4.其他报错

aaaccc444的博客 2424

c++的I/O(vc版)(一)

c++的I/O是我们最常用的库之一,也是操作复杂,功能复杂的类库之一。  在C++的程序中,很少有不用I/O的程序,但是,对于我来说,I/O我却用的出奇的差,只会几个简单的函数,尽管够用,但是却用的效率奇低,于是,在此学习c++ I/O类库的使用方法。 首先是I/O中流的概念,c++的I/O中的所有的操作都是基于流。 流i/o:要传递的数据是无结构的字节流,字符流或者任意同等大小单位

wangyanphp的专栏 1212

Camera 基础知识

Raw Sensor输出的Data格式为Raw,图像的效果处理使用BB端的ISP,BB端接收Raw data后进行一系列的图像处理(OB,Shading,AWB,Gamma,EE,ANR等),效果方面由BB端控制,需要针对不同的模组进行效果调试,Raw sensor是目前的主流,数据量比YUV Sensor小(RAW10 格式的sensor 1个pixel 10个bit)使用平台ISP处理,能支持较大的size。不过,相位对焦并不是那么完美,它对光线的要求就比较高,在弱光拍摄环境下,相位对焦就无能威力了。

手机-手表蓝牙开发工程师的博客 3062

基于YOLO-world训练模型的完整教程:从数据准备到微调训练

本文提供了YOLO-world模型训练的完整教程,涵盖从环境配置到微调训练的全流程。首先介绍了YOLO-world项目的安装与配置步骤,包括依赖安装和CUDA环境设置;接着详细说明了数据集的准备方法,包括COCO格式数据集的组织结构和自定义数据集的类别定义;然后阐述了配置文件的修改要点,包括超参数调整和数据集路径设置;最后讲解了训练命令的使用方法及常见问题的解决方案。本教程旨在帮助读者快速掌握YOLO-world模型的训练技能,适用于计算机视觉领域的研究人员和开发者。

FJN110的博客 1108

C++的I/O(vc版)(六)

首先回忆一下,我们已经分析过的类:基本的流类完成:流状态信息,格式化信息,其中一些不能用掩码表示,需要特定的数据成员,locale对象,流缓冲类指针,耦合的ostream;基本的流缓冲类完成:六个指针的存储。 这个我们分析的是basic_ostream  首先是类中会用到的类型声明: typedef basic_ostream _Myt; typedef basic_ios _Myios

wangyanphp的专栏 1678

【Bug已解决】Codex CLI 运行时出现 command not found: codex 解决方案

方案适用场景推荐指数修复 PATH 配置最常见的基础排查方向⭐⭐⭐⭐⭐检查原生二进制完整性PATH 正常但执行仍然异常⭐⭐⭐⭐统一包管理器混用多种包管理器导致混乱⭐⭐⭐⭐确认安装脚本未被跳过CI/CD 或企业策略环境⭐⭐⭐⭐排查网络下载渠道企业内网/受限网络环境⭐⭐⭐需要留意 warning 中是否涉及脚本执行失败、网络超时重试等信息,这类 warning 往往是后续问题的前兆,建议出现明显的下载/网络相关警告时就主动重新安装一次确认。Codex CLI 报。

一键难忘的博客 1万+

C++的I/O(vc版)(二)

根据流类体系,我们可以看出基本的流类是ios_base和basic_ios  首先是ios_base是流类始祖,先分析ios_base,ios_base中储存的是不依赖于读写的数据的类型的基本信息,如格式化信息、异常状态、事件回调函数等。 首先看一下数据成员: iostate _mystate;//stream state iostate _except_;//except

wangyanphp的专栏 945

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C++的I/O(vc版)(三)

前面已经分析完ios_base类了,现在来分析一下basic_ios //此处为了简洁,将许多别文件的定义搬到此文件 typedef int _Mbstatet; typedef fpos streampos; typedef streampos wstreampos; #define EOF (-1)//原本定义于stdio.h //下面是类char_traits的定义 //不同的字符集,不同

wangyanphp的专栏 1346

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

VC中C++的输入输出I/O 流函数

(1)什么是“流”?   C++中的“流”(stream)是一种抽象,它表示数据从源端流向目的端。   输入流(Input Stream)表示的是数据从输入设备(如键盘、磁盘等)流向内存,输出流(Output Stream)表示的是数据从内存流向输出设备(如屏幕、打印机、磁盘等)。输入输出流(I/O Stream)是输入流和输出流的合称。   “流”中的内容可以是任意形式的数据,例如:ASC

心在天涯 2180

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C++的I/O(vc版)(七)

首先,我们还有很多的类没有分析:istream,filestream,filebuf,还有对应得迭代器。第二,即使前面的分析也不能说明I/O的使用规范。如果想要熟练的使用I/O,建议读《C++标准程序库》,那是一本经典。第三,流的格式化读取和输出大部分依靠的是locale,而我们前面很少涉及,现在还看不懂源码,只能以后分析了。  下面摘抄《c++标准程序库》中关于如何自定义I/O操作符的说明。

wangyanphp的专栏 912

C++打造局域网聊天室第八课: 异步I/O模型及多线程

C++打造局域网聊天室第八课: 异步I/O模型及多线程

qq_59940419的博客 1506

如何在Visual Studio中新建MB-System的I/O模块

实现了在windows平台下使用Microsoft Visual Studio Community 2022 (64 位)构建MB-system的I/O模块项目,用于将国产声呐数据添加到MB-system的数据支持中去。

qq_21472607的博客 1272

socket网络通信(重叠I/O方式实现)包含4种方式

采用重叠I/O方式实现的socket网络编程,异步非阻塞方式,代码效率比阻塞式的socket编程方式高。实现了TCP server,TCP client,UDP server,UDP client,四种方式可选,可以使用在各种场合用于监控网络数据。本程序只支持单客户端和服务端的应用场合。代码封装成库形式,非常方便移植。平台使用的是VC6.0,语言用的是C++,MFC做的界面。使用ws2_32....

hill_guo的博客 824

基于函数的I/O操作(头文件stdio.h)

基于函数库的I/O是C语言标准库的功能,基于系统级I/O函数实现。 系统级I/O函数对文件的标识是文件描述符,C语言标准库中对文件的标识是指向FILE结构的指针。在头文件cstdio或stdio.h中声明了FILE结构,并对其他与标准I/O有关的常量、数据结构、函数等进行了定义。 文件是用一个指向特定结构的指针来标识的,这个特定结构就是FILE结构,它描述了包含文件描述符在内的一...

380
上一篇: C++的I/O(vc版)(四)
下一篇: C++的I/O(vc版)(六)
wangyanphp
博客等级 码龄14年 90粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值