C++ 学习指南基础(四)

目录

 

81. Formating Output

82. Functions for I/O Stream

83. File Open Mode

84. Introduction to Binary IO

85. How to Do Binary Input/Output

86. File Positioner

87. Random Access File

88. Operators and Functions

89. 2D Vector Class

90. C++ Operator Functions

91. C++11: Left Value, Pure Right Value and eXpiring Value

92. Overloading General Binary Arithmetic Operators

93. Overloading Shorthand Binary Arithmetic Operators

94. Overloading [] Operator

95. Overloading the Unary Operator

96. Overloading the - Operators

97. Overloading the ++ and -- Operators

98. Overloading << / >> Operator

99. Overloading Object Converting Operator

100. Overloading the = Operator

101. More on Operator Overloading

102. More Coding Guidelines

103. Overview of Exception-Handling

104. Exception-Handling Advantages

105. Exception Match and Exception Classes

106. Build-in Exception Classes

107. Custom Exception Classes

108. Catch Multiple Unrelated Exceptions

109. Catch Derived Exceptions

110. C++11:noexcept

111. Exception Propagation

112. Rethrowing Exceptions

113. Rethrowing Exceptions

114. When Do We Use Exceptions?

115. Meta-Programming and Generic Programming

116. Template Basics

117. Function Template

118. Function Template Instantiation

119. Make a Function Generic

120. Class Template


81. Formating Output

格式化输出

  1. setw manipulator(“设置域宽”控制符)

要包含头文件 <iomanip>

 

1.1. setw(n) 设置域宽,即数据所占的总字符数

std::cout << std::setw(3) << 'a' << std::endl;

输出:

_ _a

 

1.2. setw()控制符只对其后输出的第一个数据有效,其他控制符则对其后的所有输入输出产生影响。

std::cout << std::setw(5) << 'a' << 'b' << std::endl;

输出:

 

_ _ _ _ab

 

1.3. setw()的默认为setw(0),按实际输出

1.4. 如果输出的数值占用的宽度超过setw(int n)设置的宽度,则按实际宽度输出。

float f=0.12345; std::cout << std::setw(3) << f << std::endl;

 

输出:

 

0.12345

 

 

  1. setprecision manipulator(“设置浮点精度”控制符)

2.1. setprecision(int n)

(1) 控制显示浮点数的有效位

(2) n代表数字总位数

 

#include <iostream>

#include <iomanip>

using namespace std;

int main() {

float f = 17 / 7.0;

cout << f << endl;

cout << setprecision(0) << f << endl;

cout << setprecision(1) << f << endl;

cout << setprecision(2) << f << endl;

cout << setprecision(3) << f << endl;

cout << setprecision(6) << f << endl;

cout << setprecision(8) << f << endl;

return 0;

}

 

Visual Studio输出:

 

2.42857

2.42857

2

2.4

2.43

2.42857

2.4285715

 

Eclipse CDT + GCC 8.2输出:

 

2.42857

2

2

2.4

2.43

2.42857

2.4285715

 

  1. setfill manipulator(“设置填充字符”控制符)

3.1. setfill(c)

设置填充字符,即“<<"符号后面的数据长度小于域宽时,使用什么字符进行填充。

 

std::cout << std::setfill('*') << std::setw(5) << 'a' << std::endl;

 

输出:

 

****a

 

  1. Formatting Output in File Operation(在文件操作中格式化输入/输出)

The stream manipulator also works to format output to a file(流控制符同样可以用于文件输入/输出)

 

控制符 用途
setw(width) 设置输出字段的宽度(仅对其后第一个输出有效)
setprecision(n) 设置浮点数的输/入出精度(总有效数字个数等于n)
fixed 将浮点数以定点数形式输入/出(小数点后有效数字个数等于setprecision指定的n)
showpoint 将浮点数以带小数点和结尾0的形式输入/出,即便该浮点数没有小数部分
left 输出内容左对齐
right 输出内容右对齐
hexfloat/defaultfloat C++11新增;前者以定点科学记数法的形式输出十六进制浮点数,后者还原默认浮点格式
get_money(money)put_money(money) C++11新增;从流中读取货币值,或者将货币值输出到流。支持不同语言和地区的货币格式https://en.cppreference.com/w/cpp/io/manip/get_moneyhttps://en.cppreference.com/w/cpp/io/manip/put_money
get_time(tm, format)put_time(tm,format) C++11新增;从流中读取日期时间值,或者将日期时间值输出到流。https://en.cppreference.com/w/cpp/io/manip/get_timehttps://en.cppreference.com/w/cpp/io/manip/put_time

82. Functions for I/O Stream

用于输入/输出流的函数

 

  1. getline()

1.1. When using (>>), data are delimited by whitespace. (>>运算符用空格分隔数据)

对于文件内容:

Li Lei#Han Meimei#Adam

 

如下代码只能读入“Li”

 

ifstream input("name.txt");

std::string name;

input >> name;

 

 

1.2. Read in "Li Lei" with member function getline(char* buf, int size, char delimiter)

constexpr int SIZE{ 40 };

std::array<char , SIZE> name{};

while (!input.eof()) {// not end of file

input.getline(&name[ 0 ] , SIZE , '#');

std::cout << &name[ 0 ] << std::endl;

}

 

 

1.3. Read in "Li Lei" with non-member function std::getline(istream& is, string& str, char delimiter)

std::string name2{};

while (!input.eof()) {

std::getline(input, name2, '#');

std::cout << n << std::endl;

}

 

  1. get() and put()

Two other useful functions are get and put.

 

2.1. get: read a character

int istream::get();

istream& get (char& c);

 

2.2. put write a character.

ostream& put (char c);

 

 

  1. flush()

3.1. Flush output stream buffer (将输出流缓存中的数据写入目标文件)

ostream& flush();

 

3.2. 用法

cout.flush(); // 其它输出流对象也可以调用 flush()

cout << "Hello" << std::flush; // 与endl类似作为manipulator的调用方式

 

83. File Open Mode

文件的打开模式

 

  1. fstream and File Open Modes (fstream与文件打开模式)

       ofstream : 写数据;      ifstream  : 读数据

fstream = ofstream + ifstream

 

When opening an fstream object, a "file open mode" should be specified(创建fstream对象时,应指定文件打开模式)。

 

Mode(**模式****)** Description(**描述****)**
ios::in 打开文件读数据
ios::out 打开文件写数据
ios::app 把输出追加到文件末尾。app = append
ios::ate 打开文件,把文件光标移到末尾。ate = at end
ios::trunc 若文件存在则舍弃其内容。这是ios::out的默认行为。trunc = truncate
ios::binary 打开文件以二进制模式读写

 

  1. Combining Modes (模式组合)

2.1. Open Mode的定义

// std::ios_base::openmode 被ios继承

typedef /implementation defined/ openmode;

static constexpr openmode app = /implementation defined/

 

2.2. Combine several modes (几种模式可以组合在一起)

using the | operator (bitwise inclusive OR) (用“位或”运算符)

 

2.3. To open a file "name.txt" for appending data (打开文件name.txt追加数据)

stream.open("name.txt", ios::out | ios::app);

 

84. Introduction to Binary IO

 

二进制输入输出简介

 

 

  1. Text File vs Binary File (文本文件与二进制文件)

 

1.1. TEXT file vs BINARY file (not technically precise) (文本文件与二进制文件)

 

(1) Both stores as a sequence of bits (in binary format) (都按二进制格式存储比特序列)

(2) text file : interpreted as a sequence of characters (解释为一系列字符)

(3) binary file : interpreted as a sequence of bits. (解释为一系列比特)

 

1.2. For example, the decimal integer 199 (对于十进制整数199)

 

(1) 在文本文件中存为3个字符: '1', '9', '9';三个字符的ASCII码占3个字节:0x31, 0x39, 0x39

(2) 在二进制文件中存为字节类型的值:C7;十进制 199 = 十六进制 C7

 

 

  1. Text I/O vs Binary I/O (文本读写与二进制读写)

2.1. 文本读写:Windows文件的换行(CRLF) vs *nix文件的换行(LF)

在Windows上,'\n'输出到文件中会自动编码为'\r' '\n' 两个字符

在*nix上,'\n' 字符输出到文件中不变

 

2.2. Text I/O is built upon binary I/O to provide a level of abstraction for character encoding and decoding. (文本模式的读写是建立在二进制模式读写的基础上的,只不过是将二进制信息进行了字符编解码)

 

  1. File Open Mode: ios::binary

3.1. Binary I/O does not require conversions. (二进制读写无需信息转换)

numeric value è write (bin I/O) è file

value in memory è copy (no conversion) è file

 

3.2. How to perform binary I/O ? (如何进行二进制读写)

By default, a file is opened in text mode.(文件默认以文本模式打开)

open a file using the binary mode ios::binary.(用ios::binary以二进制模式打开文件)

 

Text I/O (**文本模式****)** Binary I/O function:(**二进制模式****)**  
operator >>; get(); getline(); read();
operator <<; put(); write();

 

85. How to Do Binary Input/Output

如何实现二进制读写

 

  1. The write Function (write函数)

1.1. prototype (函数原型)

ostream& write( const char* s, std::streamsize count )

 

1.2. 可直接将字符串写入文件

fstream fs("GreatWall.dat", ios::binary|ios::trunc);

char s[] = "ShanHaiGuan\nJuYongGuan";

fs.write(s, sizeof(s));

 

1.3. 如何将非字符数据写入文件

(1) Convert any data into a sequence of bytes (byte stream) (先将数据转换为字节序列,即字节流)

(2) Write the sequence of bytes to file with write() (再用write函数将字节序列写入文件)

 

  1. How to convert any data into byte stream? (如何将信息转换为字节流)

2.1. reinterpret_cast

该运算符有两种用途:

 

(1) cast the address of a type to another type (将一种类型的地址转为另一种类型的地址)

(2) cast the address to a number, i.e. integer (将地址转换为数值,比如转换为整数)

 

2.2. 语法: reinterpret_cast<dataType>(address)

address is the starting address of the data (address是待转换的数据的起始地址)

dataType is the data type you are converting to. (dataType是要转至的目标类型)

 

For binary I/O, dataType is char . (对于二进制I/O来说,dataType是 char)

2.3. 例子

long int x {0};

int a[3] {21,42,63};

std::string str{"Hello"};

char* p1 = reinterpret_cast<char*>(&x); // variable address

char* p2 = reinterpret_cast<char*>(a); // array address

char* p3 = reinterpret_cast<char*>(&str); // object address

 

  1. The read Function (read成员函数)

3.1. prototype (函数原型)

istream& read ( char* s, std::streamsize count );

 

3.2. 例子

// 读字符串

fstream bio("GreatWall.dat", ios::in | ios::binary);

char s[10];

bio.read(s, 5);

s[5] = '\0';

cout << s;

bio.close();

 

 

// 读其它类型数据(整数),需要使用 reinterpret_cast

fstream bio("temp.dat", ios::in | ios::binary);

int value;

bio.read(reinterpret_cast<char *>(&value), sizeof(value));

cout << value;

 

86. File Positioner

文件位置指示器

 

  1. File Positioner (文件位置指示器)

1.1. file positioner (fp):

A file consists of a sequence of bytes.(文件由字节序列构成)

File positioner is a special marker that is positioned at one of these bytes. (一个特殊标记指向其中一个字节)

 

1.2. A read or write operation takes place at the location of the file positioner. (读写操作都是从文件位置指示器所标记的位置开始)

When a file is opened, the fp is set at the beginning. (打开文件,fp指向文件头)

When you read or write data to the file, the file pointer moves forward to the next data item. (读写文件时,文件位置指示器会向后移动到下一个数据项)

 

1.3. File Positioner(文件位置指示器)的其它说法

File Pointer(文件指针):易与C语言的FILE* 混淆

File Cursor(文件光标):借用数据库中的“光标”概念

 

  1. Example of File Positioner

aFileStream.get() ---> fp = fp + 1

 

87. Random Access File

随机访问文件

 

  1. Random Access (随机访问)

1.1. Random Access means one can read/write anywhere inside a file(随机访问意味着可以读写文件的任意位置)

1.2. How?

We are able to know where the file positioner is. (我们能知道文件定位器在什么位置)

We are able to move the file positioner inside the file (我们能在文件中移动文件定位器)

Maybe we need two file positioners : one for reading, another for writing

 

1.3. 相关函数

 

· For reading (**读文件时用)** For writing(**写文件时用)**
获知文件定位器指到哪里 tellg(); tell是获知,g是get表示读文件 tellp(); tell是获知,p是put表示写文件
移动文件定位器到指定位置 seekg(); seek是寻找,g是get表示读文件 seekp(); seek是寻找,p是put表示写文件

 

  1. seek的用法

2.1. seek的原型

xxx_stream& seekg/seekp( pos_type pos );

xxx_stream& seekg/seekp( off_type off, std::ios_base::seekdir dir);

 

seekdir 文件定位方向类型 解释
std::ios_base::beg 流的开始;beg = begin
std::ios_base::end 流的结尾
std::ios_base::cur 流位置指示器的当前位置;cur = current

 

例子 解释
seekg(42L); 将文件位置指示器移动到文件的第42字节处
seekg(10L, std::ios::beg); 将文件位置指示器移动到从文件开头算起的第10字节处
seekp(-20L, std::ios::end); 将文件位置指示器移动到从文件末尾开始,倒数第20字节处
seekp(-36L, std::ios::cur); 将文件位置指示器移动到从当前位置开始,倒数第36字节处

 

88. Operators and Functions

运算符与函数

 

  1. Special Operators Usage with Objects (与对象一起用的运算符)

1.1. string类:使用“+”连接两个字符串

string s1("Hello"), s2("World!");

cout << s1 + s2 << endl;

 

1.2. array 与 vector类:使用[] 访问元素

array<char, 3> a{};

vector<char> v(3, 'a'); //'a', 'a', 'a'

a[0] v[1] = 'b';

 

1.3. path类:使用“/”连接路径元素

std::filesystem::path p{};

p = p / "C:" / "Users" / "cyd";

 

  1. The operator vs function (运算符与函数的异同)

2.1. 运算符可以看做是函数

2.2. 不同之处

2.2.1. 语法上有区别

3 * 2 //中缀式

*3 2 //前缀式

multiply ( 3, 2) ; //前缀式

3 2 * //后缀式(RPN)

 

2.2.2. 不能自定义新的运

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值