C/C++编程:流的基类std::basic_ios

1059 篇文章 274 订阅
template <class charT, class traits = char_traits<charT> >
  class basic_ios;

流的基类(与类型有关的组件):管理任意流缓冲

模板类,用于实例化所有流类的基类

类模板在它继承的ios_base组件中添加了以下信息:

 field成员函数描述
状态填充字符fill字符填充格式的字段,直到 field width (width).
状态错误状态rdstate
setstate
clear
流的当前错误状态
单个值可以通过调用 goodeoffail 和bad.来获得。
具体见 成员类型 iostate.
异常掩码exceptions引发 failure 异常的状态标志
具体见 成员类型 iostate.
Othertied streamtie指向输出流的指针,该输出流在对该流的每个I / O操作之前已刷新
流缓冲区rdbuf指向关联的指针 basic_streambuf 对象,负责所有输入/输出操作。

模板参数

charT字符类型
traits字符特征类,它定义流对象使用的字符的基本属性(请参阅char_traits

 

模板实例化

ios

流的基类(与类型有关的组件)(类)

wios

宽字符流的基类(类)

这些实例化在<iosfwd>中声明 ,通过引用将其包含在 <ios> 和 <iostream>

成员类型

成员类型描述note
char_type第一个模板参数(charT) 
traits_type 第二个模板参数(traits)默认char_traits<charT>
int_typetraits_type::int_type 
pos_typetraits_type::pos_type一般来说,与 streampos相同
off_typetraits_type::off_type一般来说,与  streamoff相同

以及从ios_base继承的成员类型 :

event

表示事件类型的类型(公共成员类型)

event_callback

事件回调函数类型(公共成员类型)

failure

流异常的基类(公共成员类)

fmtflags

流格式标志的类型(公共成员类型)

Init

初始化标准流对象(公共成员类)

iostate

流状态标志的类型(公共成员类型)

openmode

流打开模式标志的类型(公共成员类型)

seekdir

流搜索方向标志的类型(公共成员类型)

--

公共成员函数

(constructor)

构造对象(公共成员函数)

(destructor)

销毁对象(公共成员函数)

构造函数

intialization (1)    
public: explicit basic_ios (basic_streambuf<char_type,traits_type>* sb);
default (2)protected: basic_ios();
copy(3)basic_ios (const basic_ios&) = delete;
basic_ios& operator= (const basic_ios&) = delete;

构造新的 basic_ios 对象

1)  以调用init(sb) 初始化内部状态。设置关联流缓冲为 sb 。

2)默认构造函数。不初始化内部状态。必须在首次使用对象或析构函数前调用 init() ,否则行为未定义

3)复制、拷贝构造函数被删除

状态函数
good检查是否没有发生错误

eof

检查是否到达了文件末尾

fail

检查是否发生了可恢复的错误

bad

检查是否已发生不可恢复的错误

operator!

检查是否有错误发生(fail() 的同义词)

operator bool 

检查是否没有发生错误(!fail()的同义词)

rdstate

返回状态标志

setstate

设置状态标志

clear

修改状态标志

std::basic_ios::good、std::basic_ios::bad、std::basic_ios::fail

bool good() const;

若流未出现错误(最近 I/O 操作成功完成)则为 true ,否则为 false

bool bad() const;

若关联的流上已出现不可恢复的错误则返回 true 。尤其是若 rdstate() 中设置了 badbit 则返回 true 。

设置 badbit 的条件列表见 ios_base::iostate 

bool fail() const;

若关联流上已发生(可恢复的)错误则返回 true 。特别是若 rdstate() 中设置了 badbit 或 failbit 则返回 true 。

设置 failbit 或 badbit 的条件列表见 ios_base::iostate 。

下表显示 basic_ios 访问器( good()、 fail() 等)对于 ios_base::iostate 标志的所有可能组合的值:

ios_base::iostate 标志basic_ios 访问器
eofbitfailbitbadbitgood()fail()bad()eof()operator booloperator!
falsefalsefalsetruefalsefalsefalsetruefalse
falsefalsetruefalsetruetruefalsefalsetrue
falsetruefalsefalsetruefalsefalsefalsetrue
falsetruetruefalsetruetruefalsefalsetrue
truefalsefalsefalsefalsefalsetruetruefalse
truefalsetruefalsetruetruetruefalsetrue
truetruefalsefalsetruefalsetruefalsetrue
truetruetruefalsetruetruetruefalsetrue

--

// error state flags
#include <iostream>     // std::cout, std::ios
#include <sstream>      // std::stringstream

void print_state (const std::ios& stream) {
  std::cout << " good()=" << stream.good();
  std::cout << " eof()=" << stream.eof();
  std::cout << " fail()=" << stream.fail();
  std::cout << " bad()=" << stream.bad();
}

int main () {
  std::stringstream stream;

  stream.clear (stream.goodbit);
  std::cout << "goodbit:"; print_state(stream); std::cout << '\n';

  stream.clear (stream.eofbit);
  std::cout << " eofbit:"; print_state(stream); std::cout << '\n';

  stream.clear (stream.failbit);
  std::cout << "failbit:"; print_state(stream); std::cout << '\n';

  stream.clear (stream.badbit);
  std::cout << " badbit:"; print_state(stream); std::cout << '\n';

  return 0;
}

std::basic_ios::eof   

bool eof()const;

检查当前 rdstate() 是否设置了eofbit:

  • 当按与流关联的顺序到达文件结束时,所有标准输入操作都会设置此标志。
  • 也就是说检查是否到达了文件末尾
  • 具体设置 eofbit 的条件列表见 ios_base::iostate 。
    -
// ios::eof example
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream

int main () {

  std::ifstream is("example.txt");   // open file

  char c;
  while (is.get(c))                  // loop getting single characters
    std::cout << c;

  if (is.eof())                      // check for EOF
    std::cout << "[EoF reached]\n";
  else
    std::cout << "[error reading]\n";

  is.close();                        // close file

  return 0;
}

std :: basic_ios :: operator!

bool operator!() const;

检查是否有错误发生

  • 若关联流上已出现错误则返回 true 。特别是若 rdstate() 中设置了 failbit 或 badbit 则返回 true
  • fail() 的同义词
#include <iostream>
#include <fstream>
#include <cstdlib>
int main()
{
    std::ifstream file("test.txt");
    if(!file)  // operator! 用于此
    {  
        std::cout << "File opening failed\n";
        return EXIT_FAILURE;
    }
 
    // 典型的 C++ I/O 循环以 I/O 函数的返回值为循环控制条件,
    // operator bool() 用于此
    for(int n; file >> n; ) {
       std::cout << n << ' ';
    }
    std::cout << '\n';
 
    if (file.bad())
        std::cout << "I/O error while reading\n";
    else if (file.eof())
        std::cout << "End of file reached successfully\n";
    else if (file.fail())
        std::cout << "Non-integer data encountered\n";
}

std::basic_ios::operator bool

explicit operator bool() const;

检查是否没有发生错误

  • 若流无错误且已为 I/O 操作就绪则返回 true
  • !fail()的同义词
// evaluating a stream
#include <iostream>     // std::cerr
#include <fstream>      // std::ifstream

int main () {
  std::ifstream is;
  is.open ("test.txt");
  if (is) {
    // read file
  }
  else {
    std::cerr << "Error opening 'test.txt'\n";
  }
  return 0;
}
#include <iostream>
#include <sstream>
 
int main()
{
    std::istringstream s("1 2 3 error");
    int n;
    std::cout << std::boolalpha << "s is " << static_cast<bool>(s) << '\n';
    while (s >> n) {
        std::cout << n << '\n';
    }
    std::cout << "s is " << static_cast<bool>(s) << '\n';
}

std :: basic_ios :: rdstate

iostate rdstate() const;

返回当前错误状态

返回值

当前错误状态。它是位掩码类型,并且能是下列常量的组合:

常量解释
goodbit无错误
badbit不可恢复的流错误
failbit输入/输出操作失败(格式化或提取错误)
eofbit关联的输出序列已抵达文件尾

-

// getting the state of stream objects
#include <iostream>     // std::cerr
#include <fstream>      // std::ifstream

int main () {
  std::ifstream is;
  is.open ("test.txt");
  if ( (is.rdstate() & std::ifstream::failbit ) != 0 )
    std::cerr << "Error opening 'test.txt'\n";
  return 0;
}

 

#include <iostream>
#include <sstream>
 
int main()
{
  std::ostringstream stream;
 
  if (stream.rdstate() == std::ios_base::goodbit) {
    std::cout << "stream state is goodbit\n";
  }
 
  stream.setstate(std::ios_base::eofbit);
 
  // 检查状态为准确的 eofbit (无 failbit 且无 badbit )
  if (stream.rdstate() == std::ios_base::eofbit) {
    std::cout << "stream state is eofbit\n";
  }
}

std::basic_ios::setstate

void setstate( iostate state );

在当前已设置表之外,设置流错误状态标志 state 。实质上调用 clear(rdstate() | state) 。可能抛出异常。

参数

state要设置的流错误状态标志。能为下列常量的组合:
常量解释
goodbit无错误
badbit不可恢复的流错误
failbit输入/输出操作失败(格式化或提取错误)
eofbit关联的输出序列已抵达文件尾

返回值

(无)

#include <iostream>
#include <sstream>
 
int main()
{
    std::ostringstream stream;
 
    if (!stream.fail()) {
        std::cout << "stream is not fail\n";
    }
 
    stream.setstate(std::ios_base::failbit);
 
    if (stream.fail()) {
        std::cout << "now stream is fail\n";
    }
 
    if (!stream.good()) {
        std::cout << "and stream is not good\n";
    }
}

std::basic_ios::clear

void clear( std::ios_base::iostate state = std::ios_base::goodbit );
  • 通过以 state 的值赋值,设置流错误状态标志。默认赋值 std::ios_base::goodbit ,它拥有的效果为清除所有错误状态标志。
  • 若 rdbuf() 为空指针(即无关联的流缓冲),则赋值 state | badbit 。可能抛出异常

参数

state要设置的流错误状态标志。能为下列常量的组合:
常量解释
goodbit无错误
badbit不可恢复的流错误
failbit输入/输出操作失败(格式化或提取错误)
eofbit关联的输出序列已抵达文件尾

返回值

(无)

#include <iostream>
#include <string>
 
int main()
{
    double n;
    while( std::cout << "Please, enter a number\n"
           && ! (std::cin >> n) )
    {
        std::cin.clear();
        std::string line;
        std::getline(std::cin, line);
        std::cout << "I am sorry, but '" << line << "' is not a number\n";
    }
    std::cout << "Thank you for entering the number " << n << '\n';
}
// clearing errors
#include <iostream>     // std::cout
#include <fstream>      // std::fstream

int main () {
  char buffer [80];
  std::fstream myfile;

  myfile.open ("test.txt",std::fstream::in);

  myfile << "test";
  if (myfile.fail())
  {
    std::cout << "Error writing to test.txt\n";
    myfile.clear();
  }

  myfile.getline (buffer,80);
  std::cout << buffer << " successfully read from file.\n";

  return 0;
}

在此示例中,myfile打开了输入操作,但我们对其执行了输出操作,因此failbit已设置。然后该示例调用清除 为了删除该标志并允许进一步的操作

格式化
copyfmt复制格式化信息
fill管理填充字符

std :: basic_ios :: copyfmt

basic_ios& copyfmt(const basic_ios& other);

若 other 与 *this 指代同一对象,则无效果。否则复制流 other 的状态到 *this 中。以下列序列进行:

1) 传递 erase_event 为参数,调用 register_callback() 所注册的每个回调。

2) 从 other 复制所有成员对象到 *this ,除了 rdstate() 、异常掩码和 rdbuf() 。特别是复制本地环境、格式化标志、数组 std::ios_base::iword 和 std::ios_base::pword 的内容(但不是 iword 和 pword 指针本身)、回调和 tie 的流。

3) 传递 copyfmt_event为参数,调用 register_callback() 所注册的每个回调。

4) 从 other 复制异常掩码到 *this ,如同通过调用 exceptions(other.exceptions()) 

// copying formatting information
#include <iostream>     // std::cout
#include <fstream>      // std::ofstream

int main () {
  std::ofstream filestr;
  filestr.open ("test.txt");

  std::cout.fill ('*');
  std::cout.width (10);
  filestr.copyfmt (std::cout);

  std::cout << 40;
  filestr << 40;

  return 0;
}

本示例向两者输出以相同方式格式化的数字 out还有一个文件"test.txt"

 

std::basic_ios::fill

get (1)CharT fill() const;
set (2)CharT fill( CharT ch );

管理用于填充输入转换到指定宽度的填充字符。

  • 1) 返回当前的填充字符
  • 2) 设置填充字符为 ch ,返回填充字符的先前值

返回值

调用函数前的填充字符

还可以用setfill 达到同样的效果

#include <iostream>
#include <iomanip>
 
int main ()
{
  std::cout << "With default setting : " << std::setw(10) << 40 << '\n';
  char prev = std::cout.fill('x');
  std::cout << "Replaced '" << prev << "' with '"
            << std::cout.fill() << "': " << std::setw(10) << 40 << '\n';
}

杂项
exceptions管理异常掩码
imbue设置本地环境
rdbuf管理相关的流缓冲区
tie管理绑定的流
narrow窄化字符
widen拓宽字符

std::basic_ios::exceptions

get (1)std::ios_base::iostate exceptions() const;
set(2)void exceptions( std::ios_base::iostate except );

获取和设置流的异常掩码。异常掩码确定在哪些错误状态出现时抛出 failure 类型异常。

1) 返回异常掩码。

2) 设置异常掩码为 except 。

// basic_ios::exceptions
#include <iostream>     // std::cerr
#include <fstream>      // std::ifstream

int main () {
  std::ifstream file;
  file.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
  try {
    file.open ("test.txt");
    while (!file.eof()) file.get();
  }
  catch (std::ifstream::failure e) {
    std::cerr << "Exception opening/reading file";
  }

  file.close();

  return 0;
}
#include <iostream>
#include <fstream>
 
int main() 
{
    int ivalue;
    try {
        std::ifstream in("in.txt");
        in.exceptions(std::ifstream::failbit);
        in >> ivalue;
    } catch (std::ios_base::failure &fail) {
        // 此处处理异常
    }
}

std::basic_ios::imbue

std::locale imbue( const std::locale& loc );

替换当前本地环境。等效地调用 ios_base::imbue(loc) ,而若有关联流缓冲( rdbuf() != 0 ),则再调用 rdbuf()->pubimbue(loc)

#include <iostream>
#include <sstream>
#include <locale>
 
int main()
{
    std::istringstream iss;
    iss.imbue(std::locale("en_US.UTF8"));
 
    std::cout << "Current locale: " << iss.getloc().name() << '\n';
 
    iss.imbue(std::locale());
    std::cout << "Global locale : " << iss.getloc().name() << '\n';
}

std::basic_ios::rdbuf

std::basic_streambuf<CharT, Traits>* rdbuf() const;              (1)	
std::basic_streambuf<CharT, Traits>* rdbuf( std::basic_streambuf<CharT, Traits>* sb );   (2)

获取/设置流缓冲区

  • 1) 返回关联的流缓冲。若无关联流缓冲,则返回空指针。
  • 2) 设置关联流缓冲为 sb 。通过调用 clear() 清除错误状态。返回操作前的关联流缓冲。若无关联流缓冲,则返回空指针。
#include <iostream>
#include <sstream>
 
int main()
{
    std::ostringstream local;
    auto cout_buff = std::cout.rdbuf(); // 保存指向 std::cout 缓冲的指针
 
    std::cout.rdbuf(local.rdbuf()); // 以 'local' 对象的缓冲
        // 替换内部的 std::cout 缓冲
 
    // 现在 std::cout 以 'local' 缓冲工作
    // 你看不到此消息
    std::cout << "some message";
 
    // 回到旧缓冲
    std::cout.rdbuf(cout_buff);
 
    // 你将看到此消息
    std::cout << "back to default buffer\n";
 
    // 打印 'local' 内容
    std::cout << "local content: " << local.str() << "\n";
}

// redirecting cout's output thrrough its stream buffer
#include <iostream>     // std::streambuf, std::cout
#include <fstream>      // std::ofstream

int main () {
  std::streambuf *psbuf, *backup;
  std::ofstream filestr;
  filestr.open ("test.txt");

  backup = std::cout.rdbuf();     // back up cout's streambuf

  psbuf = filestr.rdbuf();        // get file's streambuf
  std::cout.rdbuf(psbuf);         // assign streambuf to cout

  std::cout << "This is written to the file";

  std::cout.rdbuf(backup);        // restore cout's original streambuf

  filestr.close();

  return 0;
}

std::basic_ios::tie

get (1)

std::basic_ostream<CharT,Traits>* tie() const;

set(2)std::basic_ostream<CharT,Traits>* tie( std::basic_ostream<CharT,Traits>* str );

默认情况下,联系标准流 cin 和 cerr 到 cout 。类似地,联系其宽对应版本 wcin 和 wcerr 到 wcout 

获取/设置绑定流

    (1)返回一个指向绑定输出流的指针。

     (2)将对象绑定到tiestr,并返回指向调用之前绑定的流的指针(如果有)。

// redefine tied object
#include <iostream>     // std::ostream, std::cout, std::cin
#include <fstream>      // std::ofstream

int main () {
  std::ostream *prevstr;
  std::ofstream ofs;
  ofs.open ("test.txt");

  std::cout << "tie example:\n";

  *std::cin.tie() << "This is inserted into cout";
  prevstr = std::cin.tie (&ofs);
  *std::cin.tie() << "This is inserted into the file";
  std::cin.tie (prevstr);

  ofs.close();

  return 0;
}

std :: basic_ios :: narrow、std::basic_ios::widen

char narrow( char_type c, char dfault ) const;
  • 将结果从 char_type 转换到 char 。若不能进行转换,则函数返回 dfault 。
  • 等效地调用 std::use_facetstd::ctype<char_type> >(getloc()).narrow(c, dfault); 。

参数

c要转换的字符
dfault若转化不成功则返回的字符

返回值

转换到标准等价物再到 char 的字符。若转换失败则返回 dfault 。

char_type widen (char c) const;
  • 将结果从 char 转换到 char_type 。
  • 等效地调用std::use_facetstd::ctype<char_type> >(getloc()).widen(c)。

受保护的成员函数

init初始化一个默认构造的std::basic_ios

move

(C++11)

从另一 std::basic_ios 移动,除了 rdbuf

swap

(C++11)

与另一 std::basic_ios 交换,除了 rdbuf
set_rdbuf替换 rdbuf 而不清除其错误状态

std::basic_ios::init

protected:
void init( std::basic_streambuf<CharT,Traits>* sb );

设置关联流缓冲为 sb 并初始化内部状态。

后置条件如下:

元素
rdbuf()sb
tie()空指针
rdstate()若 sb 不是空指针, 则为 goodbit ,否则为 badbit
exceptions()goodbit
flags()skipws | dec
width()​0​
precision()6
fill()widen(' ')
getloc()std::locale() 所返回的值的副本

此成员函数为受保护:一旦知晓实际缓冲区类型,则它为派生流类 std::basic_istream 和 std::basic_ostream 的构造函数所调用。直至调用此函数前,默认构造的 std::basic_ios 每个成员函数(包括析构函数)都引发未定义行为。注意 basic_ios 是虚基类,从而其构造函数不为直接派生类的构造函数所调用,此乃二阶段初始化为必须的原因。

参数

sb要关联到的流缓冲

参阅

(构造函数)

构造对象

--

ios_base继承的公共成员函数

 

flags

获取/设置格式标志(公共成员函数)

setf

设置特定的格式标志(公共成员函数)

unsetf

清除特定格式的标志(公共成员函数)

precision

获取/设置浮点十进制精度(公共成员函数)

width

获取/设置字段宽度(公共成员函数)

imbue

Imbue语言环境(公共成员函数)

getloc

获取当前语言环境(公共成员函数)

xalloc

获取可扩展数组的新索引[静态] (公共静态成员函数)

iword

获取可扩展数组的整数元素(公共成员函数)

pword

获取可扩展数组的指针元素(公共成员函数)

register_callback

注册事件回调函数(公共成员函数)

sync_with_stdio

设置每个输入输出操作后是否将标准C++流同步到标准C流

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值