C++文件操作、流处理、异常处理全解析
立即解锁
发布时间: 2025-08-20 01:44:37 阅读量: 1 订阅数: 3 


C++编程入门:从零基础到游戏开发
### C++ 文件操作、流处理、异常处理全解析
#### 1. 文件偏移方向与文件大小计算
在 C++ 中,文件流的偏移方向有三种,它们分别是 `ios::beg`、`ios::cur` 和 `ios::end`,其具体描述如下表所示:
| 方向 | 描述 |
| ---- | ---- |
| `ios::beg` | 偏移量从流的开头开始指定 |
| `ios::cur` | 偏移量从指针的当前位置向前指定 |
| `ios::end` | 偏移量从流的末尾开始指定 |
下面是一个使用这些偏移方向来确定文件大小的示例代码:
```cpp
#include <iostream>
#include <fstream>
using namespace std;
int main(void)
{
int n1, n2;
ifstream dragons("dragons.txt", ios::in|ios::binary);
n1 = dragons.tellg();
dragons.seekg (0, ios::end);
n2 = dragons.tellg();
cout << "The size of dragons.txt is " << n2 - n1 << "\n";
return 0;
}
```
该程序的输出结果为:
```
The size of dragons.txt is 58
```
#### 2. 二进制流的读写操作
文件流引入了两个专门用于顺序输入和输出数据的新方法:`ostream::write()` 和 `istream::read()`。它们的原型如下:
```cpp
write (char * buffer, streamsize size );
read( char * buffer, streamsize size );
```
- `write()` 方法会将 `size` 指定的字节数放在 `put` 指针之后,从而将它们写入文件。
- `read()` 方法会从 `get` 指针处获取 `size` 指定的字节数,并将这些字节放在 `buffer` 指针参数之后。
以下是一个使用这两个方法将 `dragons.txt` 文件复制到 `dragons2.txt` 文件的示例程序:
```cpp
#include <iostream>
#include <fstream>
using namespace std;
int main(void)
{
char buffer;
int index = 0;
// 文件名称
const char filename1[] = "dragons.txt";
const char filename2[] = "dragons2.txt";
// 打开文件
fstream file1(filename1, ios::in);
fstream file2(filename2, ios::out);
// 指向文件开头
file1.seekg(0, ios::beg);
file2.seekp(0, ios::beg);
// 读取第一个字符
file1.read(&buffer, 1);
// 写入剩余字符
while(file1.good() && file2.good())
{
file2.write(&buffer, 1);
index++;
file1.seekp(index);
file2.seekg(index);
file1.read(&buffer, 1);
}
// 关闭文件
file1.close();
file2.close();
return 0;
}
```
当你打开 `dragons2.txt` 文件时,它应该与 `dragons.txt` 文件内容相同。
#### 3. 常用操纵符的使用
操纵符用于操纵流中的数据。例如,你可以使用一些操纵符将所有小写字母字符转换为大写字母,或者调整数字的显示方式。大多数操纵符都包含在 `<ios>` 头文件中。以下是一些常见操纵符及其功能的列表:
| 标志 | 功能 |
| ---- | ---- |
| `dec()` | 以十进制数系统显示 |
| `hex()` | 以十六进制数系统显示 |
| `oct()` | 以八进制数系统显示 |
| `fixed()` | 插入浮点值 |
| `scientific()` | 以科学计数法插入浮点值 |
| `internal()` | 根据需要插入内部空格以填充字段宽度 |
| `left()` | 通过在右侧填充空格来左对齐字符 |
| `right()` | 通过在左侧填充空格来右对齐字符 |
| `boolalpha()` | 以符号形式表示 `true` 和 `false` |
| `noboolalpha()` | 取消 `boolalpha()` 的效果 |
| `showbase()` | 显示八进制和十六进制数的基数前缀(分别为 `0` 和 `0x`) |
| `noshowbase()` | 取消 `showbase()` 的效果 |
| `showpoint()` | 即使没有小数部分也显示小数点 |
| `noshowpoint()` | 取消 `showpoint()` 的效果 |
| `showpos()` | 在非负数前插入正号(`+`) |
| `noshowpos()` | 取消 `showpos()` 的效果 |
| `skipws()` | 跳过空格 |
| `noskipws()` | 取消 `skipws()` 的效果 |
| `unitbuf()` | 每次插入后刷新输出 |
| `nounitbuf()` | 取消 `unitbuf()` 的效果 |
| `uppercase()` | 将小写字母字符转换为大写字母 |
| `nouppercase()` | 取消 `uppercase()` 的效果 |
你可以使用 `ios::setf()` 方法并将标志作为参数,在任何流上使用这些操纵符。以下是一个在 `cout` 对象上使用这些操纵符的示例程序:
```cpp
#include <iostream>
#include <ios>
using namespace std;
int main(void)
{
cout << "Default True, False \n" << true << " " << false << "\n";
cout.setf(ios::boolalpha);
cout << "\nwith ios::boolalpha:\n" << true << " " << false << "\n";
cout << "\n140 in hex\n";
cout.setf(ios::hex, ios::basefield);
cout.setf(ios::showbase);
cout << 140 << "\n";
float f[2] = {1.0f, 775.374f};
cout << "\nDefault numeric formula\n" << f[0] << "\n" << f[1] << "\n";
cout.setf(ios::showpos);
cout << "\nand with showpos\n" << f[0] << "\n" << f[1] << "\n";
// 指示 cout 始终使用 6 位精度
cout.setf(ios::fixed);
cout << "\nand with a precision of 6\n" << f[0] << "\n" << f[1] << "\n";
return 0;
}
```
#### 4. 位字段的使用
在 C++ 中,标准数据类型是内置的,但为了存储多个较小的值,通常将标准数据类型划分为几个位字段会更高效。这些位的子部分称为位字段。例如,你可以将一个无符号字符划分为位字段。一个无符号字符由 8 位组成,这意味着所有位字段的总和必须包含 8 位。
你可以通过在声明后放置冒号并指定位字段中的位数来声明位字段。位字段必须在结构内部声明,示例如下:
```cpp
struct shortBits
{
short member1 : 2;
short member2 : 7;
short member3 : 7;
};
```
- `member1` 只能存储三个值:1 + 2。
- `member2` 和 `member3` 可以存储 127 个值:1 + 2 + 4 + 8 + 16 + 32 + 64。
#### 5. 位运算与加密程序
`<<`(左移)和 `>>`(右移)是位运算符。当进行位运算时,你会将数据类型的位向左或向右移动。例如,如果你想将一个字符向左移动 2 位,该字符的所有位都会向左移动 2 位,最左边的 2 位会被截断,最右边会添加 2 个 0。
位运算的规则如下:
- 左移一位相当于乘以 2。
- 右移一位相当于除以 2 并截断余数。
下面是一个加密程序的示例,该程序将每个字节的前四位和后四位交换:
```cpp
#include <iostream>
#include <fstream>
using namespace std;
class Encryption
{
fstream file1; // 源文件
fstream file2; // 目标文件
public:
Encryption::Encryption(char* filename1, char* filename2)
{
file1.open(filename1, ios::in | ios::out | ios::binary);
file2.open(filename2, ios::o
```
0
0
复制全文
相关推荐










