《C++ primer plus》第十七章 输入、输出和文件(一):输入和输出 学习笔记
来源:互联网 发布:ubuntu mxnet 编辑:程序博客网 时间:2024/05/16 17:09
一、C++输入和输出概述
1.C++把输入和输出看成字节流,缓冲区是用于终结的内存块,用于临时储存数据,使用缓冲区可以更高效地处理输入和输出
2.一些I/O类
streambuf类为缓冲区提供了内存,并提供了用于填充缓冲区、访问缓冲区内容、刷新缓冲区和管理缓冲区内存的类方法
ios_base类表示流的一般特征,如是否可读取,是二进制流还是文本流等。包含一些非模板的性质
ios类基于ios_base,其中包括了一个指向streambuf对象的指针成员。包含的是模板的性质
ostream类从ios类派生而来的,提供了输出方法
istream类从ios类派生而来,提供了输入方法
iostream类基于istream和ostream类的,继承了输入输出方法
3.C++的iostream类库中包含很多细节,如在程序中包含iostream文件将自动创建8个流对象(4个用于窄字符,4个用于宽字符)
cin(wcin),cout(wcout),cerr(用于显示错误消息,这个流没有缓冲,wcerr),clog(wclog,也对应着标准错误流,这个流被缓冲)
4.重定向能够改变标准输入和标准输出
假设C盘中有文件test.exe,则打开一个MD-DOS窗口(Linux/Dos/Unix能自动识别这种语法)
输入:C>test <1.txt >2.txt
此时,程序将从文件1.txt中读取输入(而不是键盘),输出到2.txt中,而不是显示屏
2.一些I/O类
streambuf类为缓冲区提供了内存,并提供了用于填充缓冲区、访问缓冲区内容、刷新缓冲区和管理缓冲区内存的类方法
ios_base类表示流的一般特征,如是否可读取,是二进制流还是文本流等。包含一些非模板的性质
ios类基于ios_base,其中包括了一个指向streambuf对象的指针成员。包含的是模板的性质
ostream类从ios类派生而来的,提供了输出方法
istream类从ios类派生而来,提供了输入方法
iostream类基于istream和ostream类的,继承了输入输出方法
3.C++的iostream类库中包含很多细节,如在程序中包含iostream文件将自动创建8个流对象(4个用于窄字符,4个用于宽字符)
cin(wcin),cout(wcout),cerr(用于显示错误消息,这个流没有缓冲,wcerr),clog(wclog,也对应着标准错误流,这个流被缓冲)
4.重定向能够改变标准输入和标准输出
假设C盘中有文件test.exe,则打开一个MD-DOS窗口(Linux/Dos/Unix能自动识别这种语法)
输入:C>test <1.txt >2.txt
此时,程序将从文件1.txt中读取输入(而不是键盘),输出到2.txt中,而不是显示屏
二、使用cout进行输出
C++将输出看成是字节流,ostream类最重要的任务之一是将数值类型转换成以文本形式表示的字节流
1.<<输出与指针
对于字符串的指针,C++自动打印出字符串,对于其他类型的指针,C++将其对应于void*,并打印地址的数值表示,如果要获得字符串的地址,需要将其强制转化为void*
2.其他ostream方法
(1)put()用于显示字符:cin.put('W').put('a');
还可以用数值型参数(如int)让函数自动转化参数为对应的char值,如:cin.put(65) //输出结果为:A
(2)write()方法用于显示真格字符串,模板原型:
basic_ostream<charT,traits>& write(const char_type* s,streamsize n)
第一个参数为要显示字符串的地址,第二个参数为要显示多少个字符,同样,cout.write也可以拼接
还可以用数值型参数(如int)让函数自动转化参数为对应的char值,如:cin.put(65) //输出结果为:A
(2)write()方法用于显示真格字符串,模板原型:
basic_ostream<charT,traits>& write(const char_type* s,streamsize n)
第一个参数为要显示字符串的地址,第二个参数为要显示多少个字符,同样,cout.write也可以拼接
3.刷新缓冲区
(1)刷新缓冲区常见的几种情况:
<1>填满缓冲区,缓冲区一般为512个字节或是其整数倍
<2>在输入即将发生时刷新缓冲区
<3>控制符flush刷新缓冲区,endl刷新缓冲区并插入一个换行符
事实上,控制符也是函数,可以直接调用flush来刷新缓冲区,如flush(cout)
不过ostream类对<<进行了重载,使得可以用cout << flush 代替flush(cout)
<1>填满缓冲区,缓冲区一般为512个字节或是其整数倍
<2>在输入即将发生时刷新缓冲区
<3>控制符flush刷新缓冲区,endl刷新缓冲区并插入一个换行符
事实上,控制符也是函数,可以直接调用flush来刷新缓冲区,如flush(cout)
不过ostream类对<<进行了重载,使得可以用cout << flush 代替flush(cout)
4.用cout进行格式化
(1)默认情况下的浮点类型显示为6位,末尾的0不显示,显示的数字位数和数字被储存时的精度没有任何关系,一般来讲,当指数大于等于6或小于等于-5时,将使用科学记数法,另外,字段宽度恰好容纳数字和负号,默认的行为对应fprintf的%g
(2)修改显示时的记数系统:dec(十进制),hex(十六进制),oct(八进制)
注:控制符不是成员函数
(3)调整字段宽度:width()是成员函数,只能用cout.width(int)进行调用,如cout.width(12)
注:width只影响显示的一个项目,之后将宽度恢复为默认值
如果在宽度为2的字段中打印一个7位值C++将增宽字段
(4)填充字符:在默认情况下,C++将使用空格填充字符,使用fill()成员函数进行改变,如:cout.fill('*')
注:与width不同的是,fill直到更改为止,该填充字符一直有效
(5)设置浮点数的精度:默认值为6,可以使用precision()成员函数进行改变,如:cout.precision(2)
注:precision直到更改为止,一直有效
(6)打印末尾的0和小数点:cout.setf(ios_base::showpoint)(因为showpoint为ios_base类定义的静态常量,所以要使用::)
此时cout不会将2.00显示为2,而是2.00000
警告:如果编译器使用的头文件为iostream.h,则有可能在setf()中使用ios参数,而不是ios_base
(7)再谈setf
setf的一种原型为:fmtflags setf(fmtflags);
fmtflags是bitmask类型的typedef名,用于储存格式标记,该名称是在ios_base类中定义的
注:bitmask类型是一种用来储存各个位值的类型;
注:控制符不是成员函数
(3)调整字段宽度:width()是成员函数,只能用cout.width(int)进行调用,如cout.width(12)
注:width只影响显示的一个项目,之后将宽度恢复为默认值
如果在宽度为2的字段中打印一个7位值C++将增宽字段
(4)填充字符:在默认情况下,C++将使用空格填充字符,使用fill()成员函数进行改变,如:cout.fill('*')
注:与width不同的是,fill直到更改为止,该填充字符一直有效
(5)设置浮点数的精度:默认值为6,可以使用precision()成员函数进行改变,如:cout.precision(2)
注:precision直到更改为止,一直有效
(6)打印末尾的0和小数点:cout.setf(ios_base::showpoint)(因为showpoint为ios_base类定义的静态常量,所以要使用::)
此时cout不会将2.00显示为2,而是2.00000
警告:如果编译器使用的头文件为iostream.h,则有可能在setf()中使用ios参数,而不是ios_base
(7)再谈setf
setf的一种原型为:fmtflags setf(fmtflags);
fmtflags是bitmask类型的typedef名,用于储存格式标记,该名称是在ios_base类中定义的
注:bitmask类型是一种用来储存各个位值的类型;
ios_base::boolalpha 输出bool值时为true和falseios_base::showpoint 显示末尾的小数点ios_base::showbase对于输出,使用C++基数前缀(0x)ios_base::uppercase 对于16进制输出,使用大写字母,E表示法ios_base::showpos在正数前面加上+
由于这些常量是在ios_base类中定义的,因此使用它们,必须使用::
第二个setf的原型:fmtflags setf(fmtflags,fmtflags),该函数返回以前的设置
第一个参数和第一个一样,包含了所需设置的fmtflags位,第二个参数指出要清除第一个参数中的哪些位
第一个参数和第一个一样,包含了所需设置的fmtflags位,第二个参数指出要清除第一个参数中的哪些位
如:cout.setf(ios_base::hex,ios_base::basefield)
由于该函数返回以前的设置,因此,要回复以前的设置,可以
ios:base old = cout.setf(ios_base::oct,ios_base::basefield);
cout.setf(old,ios_base::basefield);
使用setf的效果可以通过unsetf()消除
void unsetf(fmtflags mask);
如cout.setf(ios_base::boolalpha);
unsetf(ios_base::boolalpha);
由于该函数返回以前的设置,因此,要回复以前的设置,可以
ios:base old = cout.setf(ios_base::oct,ios_base::basefield);
cout.setf(old,ios_base::basefield);
使用setf的效果可以通过unsetf()消除
void unsetf(fmtflags mask);
如cout.setf(ios_base::boolalpha);
unsetf(ios_base::boolalpha);
(8)iomanip提供的一些标准控制符
boolalpha setf(ios_base::boolalpha)noboolalpha setf(ios_base::noboolalpha)showbase setf(ios_base::showbase)noshowbase setf(ios_base::noshowbase)showpoint setf(ios_base::showpoint)noshowpoint setf(ios_base::noshowpoint)showpos setf(ios_base::showpos)noshowpos setf(ios_base::noshowpos)uppercase setf(ios_base::uppercase)nouppercase setf(ios_base::nouppercase)internal setf(ios_base::internal, ios_base::adjustfield)left setf(ios_base::left, ios_base::adjustfield)right setf(ios_base::right, ios_base::adjustfield)dec setf(ios_base::dec, ios_base::base_field)hex setf(ios_base::hex, ios_base::base_field)oct setf(ios_base::oct, ios_base::base_field)fixed setf(ios_base::fixed, ios_base::floatfield)scientific setf(ios_base::scientific, ios_base::floatfield)
三、使用cin进行输入
1.流状态
可以使用hex、oct和dec控制符与cin一起使用
(1)cin和cout包含一个流状态,从ios_base里继承。流状态被定义为iostate类型,而iostate是一种bitmask类型
(1)cin和cout包含一个流状态,从ios_base里继承。流状态被定义为iostate类型,而iostate是一种bitmask类型
(2)
成员描述enfbit如果到文件尾,设置为1 badbit如果流被破坏,则设置为1;例如,文件读取错误failbit如果输入操作未能读取预期的字符或输出操作没有写入预期的字符,则设置为1goodbit另一种表示0的方法good()如果流可以使用(所有的位都被清除),则返回trueeof()如果eofbit被设置,则返回truebad()如果badbit被设置,则返回truefail()如果badbit或failbit被设置,则返回truerdstate()返回流状态exceptions()返回一个位掩码,支出哪些标记导致异常被引发exceptions(isostate ex)设置哪些状态将导致clear()引发异常,例如,如果ex是eofbit,则如果eofbit被设置,clear()将引发异常clear(iostate s)将流状态设置为s,s的默认值为0(goodbit);如果(restate()& exceptions())!= 0,则引发异常basic_ios::failuresetstate(iostate s)调用clear(rdstate() | s)。这将设置与s中设置的位对应的流状态位,其他流状态为保持不变
(3)设置状态
clear()和setstate()都可以重置状态,但是采取的方法不同
clear()默认参数为0,将清除全部状态位(eofbit,badbit,failbit)
而clear(eofbit)将状态设置为eofbit,另外两个状态位被清除
而setstate(eofbit)将不会影响其他的状态位
(4)I/O和异常
exceptions(isostate ex),设置哪些状态将导致clear()引发异常,例如,如果ex是eofbit,则如果eofbit被设置,clear()将引发异常,使用位操作符OR | 可以指定多位
clear()和setstate()都可以重置状态,但是采取的方法不同
clear()默认参数为0,将清除全部状态位(eofbit,badbit,failbit)
而clear(eofbit)将状态设置为eofbit,另外两个状态位被清除
而setstate(eofbit)将不会影响其他的状态位
(4)I/O和异常
exceptions(isostate ex),设置哪些状态将导致clear()引发异常,例如,如果ex是eofbit,则如果eofbit被设置,clear()将引发异常,使用位操作符OR | 可以指定多位
// cinexcp.cpp -- having cin throw an exception#include <iostream>#include <exception>int main(){ using namespace std; // have failbit cause an exception to be thrown cin.exceptions(ios_base::failbit); cout << "Enter numbers: "; int sum = 0; int input; try { while (cin >> input) { sum += input; } } catch(ios_base::failure & bf) { cout << bf.what() << endl; cout << "O! the horror!\n"; } cout << "Last value entered = " << input << endl; cout << "Sum = " << sum << endl; return 0;}
2.其他istream类方法
(1)单字符输入
cin.get(ch)赋给参数ch,返回为istream对象的引用,到达文件尾时返回值为false
ch = cin.get(),返回值为字符编码int值,到达文件尾时返回值为EOF(这里的ch最好声明为int,而不是char,因为EOF可能不能用char表示)
(2)字符串输入
istream& get(char*,int,char = '\n');
istream& getline(char*,int,char = '\n');
istream& ignore(int = 1,int = EOF)(第一个是读取的最大字符,第二个为分界符,用于读取并丢弃)
补充:getline()与string
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>&& input,
std::basic_string<CharT,Traits,Allocator>& str,
CharT delim );
(3)意外字符串的输入
getline()如果没有读取任何字符(但换行符被视为读取了一个字符)或读取了最大数目的字符,且行中还有其他字符,则设置failbit
get(char*,int)如果没有读取任何字符,则设置faileof
cin.get(ch)赋给参数ch,返回为istream对象的引用,到达文件尾时返回值为false
ch = cin.get(),返回值为字符编码int值,到达文件尾时返回值为EOF(这里的ch最好声明为int,而不是char,因为EOF可能不能用char表示)
(2)字符串输入
istream& get(char*,int,char = '\n');
istream& getline(char*,int,char = '\n');
istream& ignore(int = 1,int = EOF)(第一个是读取的最大字符,第二个为分界符,用于读取并丢弃)
补充:getline()与string
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>&& input,
std::basic_string<CharT,Traits,Allocator>& str,
CharT delim );
(3)意外字符串的输入
getline()如果没有读取任何字符(但换行符被视为读取了一个字符)或读取了最大数目的字符,且行中还有其他字符,则设置failbit
get(char*,int)如果没有读取任何字符,则设置faileof
3.其他istream方法
(1)read()
istream& read( char_type* s, int count );与getline和get不用的是,read函数不会在输入后加上'\0',因此不能用于将输入转化为字符串
read()常与ostream.wirte()结合使用,用于完成文件的输入和输出
(2)peek()
能够查看输入流的下一个字符,但是并不抽取字符
istream& read( char_type* s, int count );与getline和get不用的是,read函数不会在输入后加上'\0',因此不能用于将输入转化为字符串
read()常与ostream.wirte()结合使用,用于完成文件的输入和输出
(2)peek()
能够查看输入流的下一个字符,但是并不抽取字符
#include <sstream>#include <iostream>int main(){ std::istringstream s1("Hello, world."); char c1 = s1.peek(); char c2 = s1.get(); std::cout << "Peeked: " << c1 << " got: " << c2 << '\n';}/*输出结果为:Peeked: H got: H */(3)gcount()返回非格式化抽取字符方法读取的字符数,即get(),getline(),ignore(),read(),但是效率较慢
(4)putback()将一个字符插入到字符串中,被插入的字符将是输出流的第一个字符
#include <sstream>#include <iostream> int main(){ std::stringstream s1("Hello, world"); // IO stream s1.get(); if (s1.putback('Y')) // modifies the buffer std::cout << s1.rdbuf() << '\n'; else std::cout << "putback failed\n"; std::istringstream s2("Hello, world"); // input-only stream s2.get(); if (s2.putback('Y')) // cannot modify input-only buffer std::cout << s2.rdbuf() << '\n'; else std::cout << "putback failed\n"; s2.clear(); if (s2.putback('H')) // non-modifying putback std::cout << s2.rdbuf() << '\n'; else std::cout << "putback failed\n";}/*输出结果为:Yello, worldputback failedHello, world */
0 0
- 《C++ primer plus》第十七章 输入、输出和文件(一):输入和输出 学习笔记
- 《C++ primer plus》第十七章 输入、输出和文件(二):文件的输入和输出 学习笔记
- 2012/2/11 《C++ Primer Plus》第十七章:输入、输出和文件 学习笔记
- c++primer plus第十七章-cin输入、cout输出和文件I/O
- 《C++ Primer Plus(第六版)》(38)(第十七章 输入、输出和文件 笔记1)
- 《C++ Primer Plus(第六版)》(39)(第十七章 输入、输出和文件 笔记2)
- 《C++ Primer Plus(第六版)》(40)(第十七章 输入、输出和文件 复习题和答案)
- 《C++ Primer Plus(第六版)》(41)(第十七章 输入、输出和文件 编程练习和答案1)
- 《C++ Primer Plus(第六版)》(42)(第十七章 输入、输出和文件 编程练习和答案2)
- c++primer plus第十七章-输入和输出概述
- c++primer plus第十七章-文件输入和输出
- 【C++ primer】第十七章 输入、输出和文件
- C++ Primer Plus 第17章 输入,输出和文件
- C++ Primer Plus 之 输入、输出和文件
- C Primer Plus学习笔记----第四章字符串和格式化输入/输出
- C Primer Plus 5th 翻译 第四章:字符串和格式化输入/输出(一)
- 【读书笔记:C++ primer plus 第六版 中文版】第17章 输入、输出和文件
- C primer plus第8章(字符输入/输出和输入确认)习题
- ibatis调用mysql带OUT类型参数的存储过程
- poj1979 -- Red and Black
- Spring boot项目中展示HTML页面效果
- 【Spring】详解Spring MVC中不同格式的POST请求参数的数据类型转换过程
- [LeetCode]Remove K Digits
- 《C++ primer plus》第十七章 输入、输出和文件(一):输入和输出 学习笔记
- python 读取并显示图片的两种方法
- openCV编程总结(2)-车道线检测之Bezier曲线3次拟合
- 到底什么时候该使用MQ?
- 不要62 HDU
- 多线程开发1--线程的基本操作
- (leetcode)1. 查找数组中两个数之和为给定值Two Sum---Java
- Java 数据结构和算法 排序
- 4.《MySQL必知必会》分组与联合