Part11 流类库与输入输出 11.2输出流

1输出流概述

最重要的三个输出流
  ostream
  ofstream
  ostringstream

预先定义的输出流对象
cout 标准输出
cerr 标准错误输出,没有缓冲,发送给它的内容立即被输出。
clog 类似于cerr,但是有缓冲,缓冲区满时被输出。

 

构造输出流对象
  ofstream类支持磁盘文件输出
  如果在构造函数中指定一个文件名,当构造这个文件时该文件是自动打开的
    ofstream myFile("filename");
  可以在调用默认构造函数之后使用open成员函数打开文件
    ofstream myFile; //声明一个静态文件输出流对象
    myFile.open("filename"); //打开文件,使流对象与文件建立联系
  在构造对象或用open打开文件时可以指定模式
    ofstream myFile("filename", ios_base::out | ios_base::binary);

 

文件输出流成员函数的三种类型
  与操纵符等价的成员函数。
  执行非格式化写操作的成员函数。
  其它修改流状态且不同于操纵符或插入运算符的成员函数。

 

文件输出流成员函数
  open函数
    把流与一个特定的磁盘文件关联起来。
    需要指定打开模式。
  put函数
    把一个字符写到输出流中。
  write函数
    把内存中的一块内容写到一个文件输出流中
  seekp和tellp函数
    操作文件流的内部指针
  close函数
    关闭与一个文件输出流关联的磁盘文件
  错误处理函数
    在写到一个流时进行错误处理

 

 


2向文本输入输出
插入(<<)运算符
  为所有标准C++数据类型预先设计的,用于传送字节到一个输出流对象。

操纵符(manipulator)
  插入运算符与操纵符一起工作
    控制输出格式。
  很多操纵符都定义在
    ios_base类中(如hex())、头文件(如setprecision())。
  控制输出宽度
    在流中放入setw操纵符或调用width成员函数为每个项指定输出宽度。
  setw和width仅影响紧随其后的输出项,但其它流格式操纵符保持有效直到发生改变。
  dec、oct和hex操纵符设置输入和输出的默认进制。

 

//例11-1 使用width控制输出宽度
#include<iostream>
using namespace std;
int main(){
    double values[] = {1.23, 35.36, 653.7, 4358.24};
    for(int i = 0; i < 4; i++){
        cout.width(10);
        cout << values[i] << endl;
    }
    return 0;
}

//例11-2使用setw操纵符指定宽度
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
int main(){
    double values[] = {1.23, 35.36, 653.7, 4358.24};
    string names[] = {"Zoot", "Jimmy", "Al", "Stan"};
    for(int i = 0; i < 4; i++)
        cout << setw(6) << names[i] <<setw(10) << values[i] << endl;
    return 0;
}

//例11-3设置对齐方式
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
int main(){
    double values[] = {1.23, 35.46, 653.7, 4358,24};
    string names[] = {"Zoot", "Jimmy", "Al", "Stan"};
    for(int i = 0; i < 4; i++)
        cout << setiosflags(ios_base::left) 
            << setw(6) << names[i] 
            <<resetiosflags(ios_base::left) 
            << setw(10) << values[i] << endl;
    return 0;
}

 

setiosflags操纵符
  这个程序中,通过使用带参数的setiosflags操纵符来设置左对齐,setiosflags定义在头文件iomanip中。
  参数iosbase::left是iosbase的静态常量,因此引用时必须包括ios_base::前缀。
  这里需要用resetiosflags操纵符关闭左对齐标志。setiosflags不同于width和setw,它的影响是持久的,直到用resetiosflags重新恢复默认值时为止 。
  setiosflags的参数是该流的格式标志值,可用按位或(|)运算符进行组合

setiosflags的参数(流的格式标识)
  ios_base::skipws 在输入中跳过空白 。
  ios_base::left 左对齐值,用填充字符填充右边。
  ios_base::right 右对齐值,用填充字符填充左边(默认对齐方式)。
  ios_base::internal 在规定的宽度内,指定前缀符号之后,数值之前,插入指定的填充字符。
  ios_base::dec 以十进制形式格式化数值(默认进制)。
  ios_base::oct 以八进制形式格式化数值 。
  ios_base::hex 以十六进制形式格式化数值。
  ios_base::showbase 插入前缀符号以表明整数的数制。
  ios_base::showpoint 对浮点数值显示小数点和尾部的0 。
  ios_base::uppercase 对于十六进制数值显示大写字母A到F,对于科学格式显示大写字母E 。
  ios_base::showpos 对于非负数显示正号(“+”)。
  ios_base::scientific 以科学格式显示浮点数值。
  ios_base::fixed 以定点格式显示浮点数值(没有指数部分) 。
  ios_base::unitbuf 在每次插入之后转储并清除缓冲区内容。

精度
  浮点数输出精度的默认值是6,例如:3466.98。
  要改变精度:setprecision操纵符(定义在头文件iomanip中)。
  如果不指定fixed或scientific,精度值表示有效数字位数。
  如果设置了iosbase::fixed或iosbase::scientific精度值表示小数点之后的位数。

//例11-4控制输出精度——未指定fixed或scientific
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
int main(){
    double values[] = {1.23, 35.46, 653.7, 4358,24};
    string names[] = {"Zoot", "Jimmy", "Al", "Stan"};
    for(int i = 0; i < 4; i++)
        cout << setiosflags(ios_base::left)
            << setw(6) << names[i]
            << resetiosflags(ios_base::left)    //清除左对齐
            << setw(10) << setprecision(1) << values[i] << endl;
    return 0;
}

//例11-4控制输出精度——指定fixed
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main() {
    double values[] = { 1.23, 35.36, 653.7, 4358.24 };
    string names[] = { "Zoot", "Jimmy", "Al", "Stan" };
    cout << setiosflags(ios_base::fixed);   
    for (int i=0;i<4;i++)
      cout << setiosflags(ios_base::left)
        << setw(6) << names[i]
        << resetiosflags(ios_base::left)//清除左对齐设置
        << setw(10) << setprecision(1) << values[i] << endl;
    return 0;
}

//例11-4控制输出精度——指定scientific
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main() {
    double values[] = { 1.23, 35.36, 653.7, 4358.24 };
    string names[] = { "Zoot", "Jimmy", "Al", "Stan" };
    cout << setiosflags(ios_base::scientific);
    for (int i=0;i<4;i++)
      cout << setiosflags(ios_base::left)
        << setw(6) << names[i]
        << resetiosflags(ios_base::left)//清除左对齐设置
        << setw(10) << setprecision(1) << values[i] << endl;
    return 0;
}

 

 


3向二进制文件输出
  二进制文件流
  使用ofstream构造函数中的模式参量指定二进制输出模式;
  以通常方式构造一个流,然后使用setmode成员函数,在文件打开后改变模式;
  通过二进制文件输出流对象完成输出。

//例11-5 向二进制文件输出
#include<fstream>
using namespace std;
struct Date{
    int mon, day, year; 
};
int main(){
    Date dt = {6, 10, 92};
    oftream file("date.dat", ios_base::binary);
    file.write(reinterpret_cast<char *>(&dt), sizeof(dt));
    file.close();
    return 0;
}

 

4向字符串输出
字符串输出流( ostringstream )
  用于构造字符串
  功能
    支持ofstream类的除open、close外的所有操作
    str函数可以返回当前已构造的字符串
  典型应用
    将数值转换为字符串

//例11-6用ostringstream将数值转换为字符串
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
template<class T>
inline string toString(const T &v){
    ostringstream os;
    os << v;    //将变量v的值写入字符串流
    return os.str();
}
int main(){
    string str1 = toString(5);
    cout << str1 << endl;
    string str2 = toString(1.2);
    cout << str2 << endl;
    return 0;
}

 

posted @ 2018-01-09 02:49  LeoSirius  阅读(165)  评论(0编辑  收藏  举报