流的概念及应用于处理文件

参考:《Big C++ 》

输入/输出库是基于流的概念。
输入流是数据的源头
输出流是数据的汇集/数据的目标
最常见的数据源头和数据目标是————硬盘上的文件·

三种类型的文件流

  1. ifstream(input file stream)
  2. ofstream
  3. fstream

要包含**< fstream >**head文件

对于文件流的操作
5. 从文件流中读取内容
1.1. open

string filename;
cin>> filename;
ifstream in_file; //declare a ifsream named in_file
in_file.open(filename.c_str());//将c++ 的string变量转换为C语言的字符串(char[])

可以从close这一(流里面的)成员函数(method)关闭流
in_file.close();
1.2. 读入

string name;
double value;
in_file >>name>>value;

if(!in_file.fail()){ //读入成功
//handle the input
}

小提示:在调用open之后,最好立即测试是否fail掉,不要在读取之后的时候才测试

  1. 写入文件
    需要ofstream或者fstream 变量


ofstream out_file;
out_file.open(“output.txt”);
outfile << name << " " << value << endl;

从文件中读取数据和读取见键盘输入一样容易。



//以下是例程
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

/**
    读取名字信息,如果tota>=0, 则打印该名字,并根据实际情况修改total
    @ param in_file 输入流
    @ param total 还需处理的部分占总数的百分比(理解,还能被处理的名字的数量占总数的百分比)
*/

//传入实参
void process_name(ifstream &in_file, double &total){
    string name;
    int count;
    double percent;

    in_file >> name>> count>>percent;

    //if 读取失败
    if(in_file.fail())
        return;

    // 还能继续处理,收集的名字应的人数占总数的比尚未超过total(%)
    if(total > 0)
        cout << name << " ";
    total = total -percent;


}


int main(){
    ifstream in_file;
    in_file.open("babynames.txt");

    if(in_file.fail()){
        cout<<"Failure Reading!"<<endl;
        return 0;
    }


    double boy_total = 50;
    double girl_total = 50;

    while(boy_total>0 || girl_total > 0){
        int level;
        in_file>>level;

        if(in_file.fail())
            return 0;

        cout<< level<< " ";

        process_name(in_file, boy_total);
        process_name(in_file,girl_total);

        cout<<endl;

    }
    return 0;
}

刚才所看到的“逐个读取“的流的形式
这种形式最simple,但可以想见还可以直接读取文本的输入
这样更符合人的阅读方式,不是逐词逐词读
而是一大段一大段地读

  1. 读入单词
    读入单词就是
    string word;
    in_file >> word;

这两句代码的底层mechanism就是,先从输入流,也就是被打开的文件中删除任何空白字符
也就是跳过所有空白字符
所谓“空白字符”,就是

  1. 空格

  2. 制表符

  3. 换行符
    从而第一个不是空白的character 将成为字符串word的第一个字符
    然后继续添加字符,知道再次出现空白字符而停止,或者达到EOF
    但单词后面的空白字符尚不会被跳过(不从流中删除)————用心感受原理,理解

  4. 读取字符
    call get!
    char ch;
    in_file.get(ch);

返回一个“not failed” 状态

while(in_file.get(ch)){
//handle ch;
}

get 函数会读取空白字符,若对空白字符不感兴趣,就用>>这个operator

in_file >> ch;//读取一个(下一个)non-blank character

  1. 读取一行

“getline函数读取一整行输入,包括行末的换行符。它将(除了换行符以外的)所有字符放入字符串line中”
string line;
getline(in_file, line);

写入文本并输出

<<

  1. 往流中写入单个字符 put方法
    out_file.put(ch);

控制输出格式 ———— 流operator

设置字长为10, 在写入下一个数据项时,会产生足够的空格填充该项,使得该输出能够达到10个字符的长度
当然,如果该项的长度超过10个字符,则setw(10)自动失效
out_file << setw(10)
//前导0填充
out_file <<setfill(‘0’) << setw(2)<<hours
<<’:’ << setw(2) << minutes<< setfill(’ ');

左对齐右对齐

out_file << left << setw(10) << word << right << setw(10) << number;

4. 解析和格式化字符串

istringstream类 从字符串中读取字符
ostringstream 将字符写入字符串中

字符串流(stringstream)和其他类具有相同的公共接口

包含sstream头文件

istringstream strm;

//str 函数,将流设置成为“要读取的字符串”

strm.str(“January 24, 1973”);

string month;
int day;
string comma;
int year;

strm >> month >> day >> comma >> year;

以下的凯撒密码程序需要用命令行模式才能运行

// caesar凯撒密码
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

/**
    使用凯撒密码对流数据进行
    加密

    @参数 in  读取的流
    @参数 out 写入的流

    @参数 k 加密密钥

*/
void encrypt_file(ifstream &in, ofstream &out, int k){
    char ch;
    while(in.get(ch)){
        //encryption
        out.put(ch+k);
    }
}

int main(int argc, char *argv[]){
    int key = 3;
    int file_count = 0;

    ifstream in_file;
    ofstream out_file;

    for(int i = 1;i<argc;i++){
        string arg = argv[i];
        if(arg == "-d")
            key = -3;
        else{
            file_count ++ ;
            if(file_count == 1){
                in_file.open(arg);
                if(in_file.fail()){
                    cout<< "Error opening input file" << arg <<endl;
                    return 1;
                }
            }
            else if(file_count == 2){
                out_file.open(arg);
                if(out_file.fail()){
                cout<< "Error opening output file" << arg <<endl;
                return 1;
                }
            }


        }
    }

    if (file_count !=2){
        cout<< "Usage: " <<argv[0] << " [-d] infile outfile"<<endl;
    return 1;
    }

    encrypt_file(in_file,out_file, key);
    return 0;
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值