c++二进制
时间: 2025-05-03 07:39:47 浏览: 27
### C++ 中与二进制相关的操作或概念
#### 一、C++ 的二进制文件操作
在 C++ 中,可以通过 `std::fstream` 或其派生类 `std::ifstream` 和 `std::ofstream` 来处理二进制文件。为了确保以二进制模式打开文件,需指定标志 `std::ios::binary`。
下面是一个简单的例子展示如何向二进制文件写入数据并从中读取:
```cpp
#include <iostream>
#include <fstream>
struct Data {
int id;
double value;
};
int main() {
// 写入二进制文件
Data dataToWrite = {1, 3.14};
std::ofstream outFile("data.bin", std::ios::binary);
if (outFile.is_open()) {
outFile.write(reinterpret_cast<char*>(&dataToWrite), sizeof(Data));
outFile.close();
} else {
std::cerr << "无法打开文件用于写入!" << std::endl;
}
// 从二进制文件读取
Data dataRead;
std::ifstream inFile("data.bin", std::ios::binary);
if (inFile.is_open()) {
inFile.read(reinterpret_cast<char*>(&dataRead), sizeof(Data));
inFile.close();
std::cout << "ID: " << dataRead.id << ", Value: " << dataRead.value << std::endl;
} else {
std::cerr << "无法打开文件用于读取!" << std::endl;
}
}
```
上述代码展示了如何通过 `write()` 函数将结构体对象写入二进制文件以及通过 `read()` 函数将其恢复[^1]。
---
#### 二、C++ 的位运算
C++ 提供了一系列位运算符来直接操作整型变量中的每一位。常见的位运算符及其用途如下表所示:
| 运算符 | 描述 |
|--------|--------------------------|
| & | 按位与 |
| \| | 按位或 |
| ^ | 按位异或 |
| ~ | 取反(按位非) |
| << | 左移 |
| >> | 右移 |
以下是一些典型的位运算应用实例:
##### 示例 1:设置某一位为 1
假设需要将整数的第 n 位置为 1,则可以使用左移和按位或运算完成此任务:
```cpp
unsigned int setBit(unsigned int num, unsigned int position) {
return num | (1 << position);
}
// 测试
unsigned int number = 0b0000'1010; // 十进制表示为 10
unsigned int result = setBit(number, 2); // 设置第 2 位为 1
std::cout << std::hex << result << std::endl; // 输出应为 'a'
```
##### 示例 2:清除某一位
要清除某个特定位置上的比特值(即设为 0),可采用按位与和补码的方式实现:
```cpp
unsigned int clearBit(unsigned int num, unsigned int position) {
return num & ~(1 << position);
}
// 测试
unsigned int number = 0b0000'1010; // 十进制表示为 10
unsigned int result = clearBit(number, 1); // 清除第 1 位
std::cout << std::dec << result << std::endl; // 输出应为 '8'
```
##### 示例 3:判断某一位是否被置位
利用按位与检测目标位的状态:
```cpp
bool isBitSet(unsigned int num, unsigned int position) {
return ((num >> position) & 1) != 0;
}
// 测试
unsigned int number = 0b0000'1010; // 十进制表示为 10
if (isBitSet(number, 3)) {
std::cout << "第三位已被置位" << std::endl;
} else {
std::cout << "第三位未被置位" << std::endl;
}
```
以上示例说明了如何运用基本的位运算技巧解决实际编程需求[^2]。
---
#### 三、C++ 打开文件的不同模式
除了标准输入输出外,还可以结合不同的标志组合控制文件的行为方式。下列表格总结了几种常用的文件打开选项及其对应的含义:
| 标志 | 含义 |
|-----------------------|--------------------------------------------------------------------------------------------|
| `std::ios::in` | 打开文件仅作读取 |
| `std::ios::out` | 打开文件准备写入;如果文件不存在则创建新文件 |
| `std::ios::app` | 将所有输出附加至现有文件末尾 |
| `std::ios::trunc` | 如果文件已存在,则删除原有内容 |
| `std::ios::binary` | 使用二进制而非文本模式 |
当涉及复杂的文件访问场景时,可以选择多个标志联合起来满足具体的需求。例如,“w+”对应的是 `std::ios::in | std::ios::out | std::ios::trunc` 组合效果[^3]。
---
#### 四、综合案例分析
考虑这样一个情景——我们需要保存一组学生记录到磁盘上,并稍后再加载它们回来显示给用户看。这里给出完整的解决方案框架作为参考学习材料之一部分。
```cpp
#include <vector>
#include <string>
using namespace std;
class StudentRecord {
public:
string name;
float score;
};
void saveRecords(const vector<StudentRecord>& records, const char* filename) {
ofstream file(filename, ios::binary);
if (!file) throw runtime_error("Cannot open file for writing!");
size_t count = records.size();
file.write((char*)&count, sizeof(count)); // Write the total record count first
for(auto& rec : records){
size_t length = rec.name.length()+1; // Include null terminator
file.write((char*)&length, sizeof(length));
file.write(rec.name.c_str(), length);
file.write((char*)&rec.score, sizeof(rec.score));
}
}
vector<StudentRecord> loadRecords(const char* filename){
ifstream file(filename, ios::binary);
if(!file) throw runtime_error("Cannot open file for reading!");
vector<StudentRecord> results;
size_t count=0;
file.read((char*)&count,sizeof(count));
while(count--){
StudentRecord temp;
size_t length=0;
file.read((char*)&length,sizeof(length));
temp.name.resize(length-1); //-1 excludes '\0', but we read it anyway.
file.read(&temp.name[0],length);
file.read((char*)&temp.score,sizeof(temp.score));
results.push_back(std::move(temp));
}
return results;
}
```
该程序片段定义了一个存储学生成绩的功能模块,既包含了序列化过程也涵盖了相应的反序列化进程。
---
阅读全文
相关推荐













