重读C++Primer-1

我们来看一个例子:
某个书店将每本售出图书的书名和出版社输入到一个文件中,这些信息以书售出的时间,顺序输入。
每两周店主将手工计算每本书的销售量,以及每个出版社的销售量。
报表以出版社名称的字母顺序排列以便下订单。

书店问题可以分解成四个子问题或任务
1 读销售文件
2 根据书名和出版社计算销售量
3 以出版社名称对书名进行排序
4 输出结果

第3个子问题解决起来还是有些大,所以对这个子问题重复我们的做法,继续分解
3a 按出版社排序
3b 对每个出版社的书按书名排序
3c 在每个出版社的组中比较相邻的书名如果两者匹配增加第一个的数量删除第二个

任务的原始顺序是不正确的,正确的动作序列应该是
l 读销售文件
2 对文件排序——先按出版社然后在出版社内部按书名排序
3 压缩重复的书名
4 将结果写入文件

int main()
{
    readIn();
    sort();
    compact();
    print();
    return 0;
}

哑函数实例:
提供函数readln() sort() compact()以及print()的定义,
void readIn() { cout << "readIn()/n"; }
void sort() { cout << "sort()/n"; }
void compact() { cout << "compact()/n"; }
void print() { cout << "print()/n"; }

标准C++头文件没有后缀

一段完整的程序
///

#include <iostream>
using namespace std;

void read() { cout << "read()/n"; }
void sort() { cout << "sort()/n"; }
void compact() { cout << "compact()/n"; }
void write() { cout << "write()/n"; }

int main()
{
    read();
    sort();
    compact();
    write();
    return 0;
}

///

// 为了使用string 对象下面的头文件是必需的
#include <string>
string current_chapter = "Getting Started";
// 为了使用vector 对象下面的头文件是必需的
#include <vector>
vector<string> chapter_titles( 20);


如果文件名用尖括号< 和> 括起来表明这个文件是一个工程或标准头文件查找过程会检查预定义的目录
#include <some_file.h>
如果文件名用一对引号括起来则表明该文件是用户提供的头文件查找该文件时将从当前文件目录开始
#include "my_file.h"

条件指示符#ifndef 检查BOOKSTORE_H 在前面是否已经被定义
#ifndef BOOKSTORE_H
#define BOOKSTORE_H
/* Bookstore.h 的内容 */
#endif

#ifdef 指示符常被用来判断一个预处理器常量是否已被定义以便有条件地包含程序代码
///
int main()
{
    #ifdef DEBUG
    cout << "Beginning execution of main()/n";
    #endif
 
    string word;
    vector< string > text;
    while ( cin >> word )
    {
        #ifdef DEBUG
        cout << "word read: " << word << "/n";
        #endif
        text.push_back( word );
    }
    // ...
}
/

编译C++程序时编译器自动定义了一个预处理器名字__cplusplus, 注意前面有两个下划线
因此我们可以根据它来判断该程序是否是C++程序,以便有条件地包含一些代码
/
#ifdef __cplusplus
// 不错我们要编译C++
extern "C"
#endif
int min( int, int );
/
在编译标准C 时编译器将自动定义名字__STDC__

__LINE__记录文件已经被编译的行数
__FILE__包含正在被编译的文件的名字

if ( element_count == 0 )
cerr << "Error: " << __FILE__
    << " : line " << __LINE__
    << "element_count must be non-zero./n";

另外两个预定义名字分别包含当前被编译文件的编译时间__TIME__ 和日期__DATE__
时间格式为hh:mm:ss

assert()是C语言标准库中提供的一个通用预处理器宏。
在代码中常利用assert()来判断一个必需的前提条件以便程序能够正确执行。
#include <assert.h>
assert( filename != 0 );
assert.h 是C 库头文件的C 名字。
C++程序可以通过C 库的C 字或C++名字来使用它。这个头文件的C++名字是cassert。
C 库头文件的C++名字总是以字母C 开头,后面是去掉后缀.h 的C 名字。
由于在各种C++实现中头文件的后缀各不相同因此标准C++头文件没有指定后缀
#include <cassert>
将cassert 的内容被读入到我们的文本文件中,但是由于所有的C++库名字是在名字空间std 中被定义的。
因而在我们的程序文本文件中它们是不可见的除非用下面的using 指示符显式地使其可见
using namespace std;

终端输入,也被称为标准输入standard input与预定义的iostream对象 cin 绑定在一起。
直接向终端输出,也被称为标准输出standard output与预定义的iostream对象cout绑定在一起。
第三个预定义iostream 对象cerr 称为标准错误standard error 也与终端绑定。
任何要想使用iostream 库的程序必须包含相关的系统头文件
#include <iostream>

除了显式地使用换行符'/n'外, 我们还可以使用预定义的iostream 操纵符manipulator endl
endl 在输出流中插入一个换行符然后刷新输出缓冲区我们一般不写
cout << '/n';
而是写成
cout << endl;

为了打开一个文件供输入或输出除了iostream 头文件外还必须包含头文件
#include <fstream>
为了打开一个输出文件我们必须声明一个ofstream 类型的对象
ofstream outfile( "name-of-file" );
为了测试是否已经成功地打开了一个文件我们可以写出这样的代码
// 如文件不能打开值为false
if ( ! outfile )
    cerr << "Sorry! We were unable to open the file!/n";
类似地为了打开一个文件供输入我们必须声明一个ifstream 类型的对象
ifstream infile( "name of file" );
if ( ! infile )
    cerr << "Sorry! We were unable to open the file!/n";

一个简单的程序
它从一个名为in_file 的文本文件中读取单词,
然后把每个词写到一个名为out_file 的输出文件中,并且每个词之间用空格分开
///
#include <iostream>
#include <fstream>
#include <string>

int main()
{
    ofstream outfile( "out_file" );
    ifstream infile( "in_file" );
    if ( ! infile ) {
        cerr << "error: unable to open input file!/n";
        return -1;
    }
    if ( ! outfile ) {
        cerr << "error: unable to open output file!/n";
       return -2;
    }
    string word;
    while ( infile >> word )
       outfile << word << ' ';
    return 0;
}
///


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值