首页 > 代码库 > 【ThinkingInC++】72、输入输出流

【ThinkingInC++】72、输入输出流

第四章 输入输出流

Strfiile.cpp

 

/**
* 书本:【ThinkingInC++】
* 功能:一个文件的输入输出流
* 时间:2014年10月12日15:15:59
* 作者:cutter_point
*/
#include <iostream> //很多平台上<fstream>会自动包含<iostream>但是不是所有
#include <fstream>
#include "../require.h"
using namespace std;
int main()
{
    const int SZ=100;   //缓冲池的大小
    char buf[SZ];   //缓冲区
    {
        ifstream in("Strfile.cpp"); //读入文件
        assure(in, "Strfile.cpp");  //确定文件被打开了
        ofstream out("Strfile.txt");    //输出文件
        assure(out, "Strfile.txt");
        int i=1;    //表示第一行
        while(in.get(buf, SZ))  //读入SZ-1个字符或者,遇到'\n'
        {
            in.get();   //去除'\n',因为上面的是没有读入'\n'的,这里吧'\n'读入,但是不处理
            cout<<buf<<endl;    //这里必须加endl;,不然不会换行
            out<<i++<<"\t: "<<buf<<endl;
        }
    }
    ifstream in("Strfile.txt");
    assure(in, "Strfile.txt");
    while(in.getline(buf, SZ))
    {
        char* cp=buf;
        while(*cp != ':')   //为了去除前面的序号
            ++cp;
        cp+=2;  //这是为了去除 ": "
        cout<<cp<<endl;
    }
    return 0;
}


4.6 在输入输出流中定位

 标志                                                   功能

Ios::in           打开输入文件。将这种打开模式用于ofstream可以使得现存

                 文件不被截断

Ios::out          打开输出文件。

Ios::app          打开一个仅用于追加的输出文件

Ios::ate           打开一个已存在的文件,并把文件指针指向文件的末尾

                  如果文件存在,则截断旧文件

Ios::trunc          如果文件存在,则截断旧文件

Ios::binary         以二进制方式打开文件。默认打开为文本方式

 

read(unsigned char *buf,int num);

write(const unsigned char *buf,int num);


read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount()来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。

* seekg() 对输入文件定位,有两个参数:
 *     第一个:表示偏移量,可正可负,正表示向后,负表示向前
 *     第二个:偏移的基地址,可以是:
 *              ios::beg    输入流的开始
 *              ios::cur    输入流的当前位置
 *              ios::end    输入流的结束

 

 

4.7 字符串输入输出流

ws指的是std::ws,是用来去除空格的
比如:

int i;
float f;
char buf[100];
cin >> i >> f;
cin >> std::ws;
cin.getline(buf, 100);


这段程序在运行时,你需要输入一个整形数,然后输入一个空格,再输入一个浮点数。然后,你可以输入若干空格,最后输入字符串。
cin在读取到整数和浮点数之后,会继续读取你输入的字符串,并且忽略浮点数和字符串之间的若干空格。

 

Ostring.cpp

 

/**
* 书本:【ThinkingInC++】
* 功能:输出字符串流
* 时间:2014年10月12日15:17:02
* 作者:cutter_point
*/

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main()
{
    cout<<"输入一个int,一个float,一串字符串";
    int i;
    float f;
    cin>>i>>f;
    cin>>ws;    //去除空格,ws是std里面的,为了忽略空格的
    string stuff;
    getline(cin, stuff);    //得到一行字符串
    ostringstream os;   //字符串输出流
    os<<"integer = "<<i<<endl;
    os<<"float = "<<f<<endl;
    os<<"string = "<<stuff<<endl;
    string result=os.str();
    cout<<result<<endl;

    return 0;
}



 

4.8 输入流的格式化

开/关标志

作用

Ios::skipws

跳过空格

Ios::showbase

打印整数值的时候指出数字的基数

Ios::showpoint

显示浮点值得小数点并截断数字末尾的0

Ios::uppercase

显示十六进制值时使用大写A~F,显示科学计数中的E

Ios::showpos

显示正数前的加号(+)

Ios::unitbuf

“单元缓冲区”。每次插入后刷新

 

 

 

Ios::basefield

作用

Ios::dec

十进制

Ios::hex

十六进制

Ios::oct

八进制

 

 

Ios::floatfield

作用

Ios::scientific

以科学计数法形式显示浮点数

Ios::fixed

以固定格式显示浮点数

“automatic”

精度域指示所有有效数字的位数

 

 

Ios::adjustfield

作用

Ios::left

数值左对齐

Ios::right

右对齐

Ios::internal

前面的正负号左对齐,后面数值右对齐

 

 

函数

作用

Int ios::width()

返回当前宽度。默认为0

Int ios::width(int n)

设定宽度,并返回当前宽度

Int ios::fill()

返回当前填充字符,默认是空格

Int ios::fill(int n)

设定填充字符,并返回前面的字符

Int ios::precision()

返回当前浮点数精度

Int ios::precision(int n)

设定浮点数精度,返回先前的精度。

 

 

Format.cpp

 

/**
* 书本:【ThinkingInC++】
* 功能:关于一些格式化域的使用
* 时间:2014年10月12日15:17:35
* 作者:cutter_point
*/

#include <iostream>
#include <fstream>

using namespace std;

#define D(A) T<<#A<<endl;  A    //D(A)代表先执行后面那个,然后还要执行A代表的意思

int main()
{
    ofstream T("format.txt");
    D(int i=47);
    D(float f=123456789.543235453);
    const char* s="I`m cutter_point";
    D(T.setf(ios::unitbuf);)    //“单元缓冲区”。每次插入后刷新
    D(T.setf(ios::showbase);)   //打印整数值的时候指出数字的基数
    D(T.setf(ios::uppercase | ios::showpos);)
    D(T<<i<<endl;)  //默认是10进制
    D(T.setf(ios::hex, ios::basefield);)
    D(T<<i<<endl;)
    D(T.setf(ios::oct, ios::basefield);)
    D(T<<i<<endl;)
    D(T.unsetf(ios::showbase);) //打印整数值的时候指出数字的基数
    D(T.setf(ios::dec, ios::basefield);)
    D(T.setf(ios::left, ios::adjustfield);) //数值左对齐
    D(T.fill('0');)
    D(T<<"fill char: "<<T.fill()<<endl;)
    D(T.width(10);)
    T<<i<<endl;
    //右对齐
    D(T.setf(ios::right, ios::adjustfield);)
    D(T.width(10);)
    T<<i<<endl;
    //前面的正负号左对齐,后面数值右对齐
    D(T.setf(ios::internal, ios::adjustfield);)
    D(T.width(10);)
    T<<i<<endl;
    D(T<<i<<endl;)

    D(T.unsetf(ios::showpos);)
    D(T.setf(ios::showpoint);)
    D(T<<"prec = "<<T.precision()<<endl;)   //设定浮点数精度,返回先前的精度。
    D(T.setf(ios::scientific, ios::floatfield);)
    D(T<<endl<<f<<endl;)
    D(T.unsetf(ios::uppercase);)
    D(T<<endl<<f<<endl;)
    D(T.setf(ios::fixed, ios::floatfield);) //以固定格式显示浮点数
    D(T<<f<<endl;)
    D(T.precision(20);)
    D(T<<"prec = "<<T.precision()<<endl;)   //设定浮点数精度,返回先前的精度。
    D(T<<endl<<f<<endl;)
    D(T.setf(ios::scientific, ios::floatfield);)
    D(T<<endl<<f<<endl;)
    D(T.setf(ios::fixed, ios::floatfield);) //以固定格式显示浮点数
    D(T<<f<<endl;)

    D(T.width(10);)
    T<<s<<endl;
    D(T.width(40);)
    T<<s<<endl;
    D(T.setf(ios::left, ios::adjustfield);)
    D(T.width(40);)
    T<<s<<endl;

    return 0;
}


 

4.9 操纵算子

操纵算子

作用

Showbase

输出整形数时显示数字的基数(dec, oct或hex)

Noshowbase

 

Showpos

显示正数前面的正号(+)

Noshowpos

 

Uppercase

用大写的A~F显示十六进制数,在科学计数型数字中使用大写的E

Nouppercase

 

Showpoint

显示浮点数的十进制小数点和尾部的0

Noshowpoint

 

Skipws

跳过输入中的空格

Noskipws

 

Left

数值左对齐

Right

右对齐,向左边填充字符

Internal

把填充字符放到引导符或基数指示符和数值之间

Scientific

指出浮点数的优先输出格式

Fixed

 

 

 

4.9 操作算子

4.9.3 效用算子

自己创建算子。

 

Effector.cpp

 

/**
* 书本:【ThinkingInC++】
* 功能:效用算子
* 时间:2014年10月12日15:18:32
* 作者:cutter_point
*/

#include <cassert>
#include <limits>
#include <sstream>
#include <string>
#include <iostream>

using namespace std;

class Fixw
{
    string str;
public:
    Fixw(const string& s, int width) : str(s, 0, width) {}
    friend ostream& operator<<(ostream& os, const Fixw& fw)
    {
        return os<<fw.str;
    }
};

typedef unsigned long ulong;    //二进制输出

class Bin
{
    ulong n;
public:
    Bin(ulong nn) { n=nn; }
    friend ostream& operator<<(ostream& os, const Bin& b)
    {
        const ulong ULMAX=numeric_limits<ulong>::max();
        ulong bit=~(ULMAX>>1);
        while(bit)
        {
            os<<(b.n & bit ? '1' : '0');
            bit>>=1;
        }
        return os;
    }
};

int main()
{
    string words="C++ that make us happy, make us wise";
    for(int i=words.size() ; --i >= 0 ;)
    {
        ostringstream s;    //输出流
        s<<Fixw(words, i);
        assert(s.str() == words.substr(0, i));
        cout<<s.str()<<endl;
    }
    ostringstream xs, ys;
    xs<<Bin(0xCAFEBABEUL);
    cout<<xs.str()<<endl;
    ys<<Bin(0x76543210UL);
    cout<<ys.str()<<endl;

    return 0;
}


【ThinkingInC++】72、输入输出流