二.protobuf的使用

一.回顾

上篇博客链接:

https://blog.csdn.net/weixin_60668256/article/details/155913219?fromshare=blogdetail&sharetype=blogdetail&sharerId=155913219&sharerefer=PC&sharesource=weixin_60668256&sharefrom=from_link

二.enum类型

1.语法

2.定义时注意

在同一个.proto文件中,不能有同名的枚举名字,但是枚举值可以一样

在不同的.proto文件中,也不可以有同名的枚举名字,但是如果加上了package还是可以同名的

三.升级通讯录到2.1版本

1.增加enum类型

cpp 复制代码
syntax = "proto3";
package contacts2;


//定义联系人message
message PeopleInfo
{
    string name = 1; //姓名
    int32 age = 2;   //年龄
    message Phone
    {
        string number = 1;
        enum PhoneType
        {
            MP = 0; //移动电话
            TEL = 1; //固定电话
        }
        PhoneType type = 2;
    }
    repeated Phone phone = 3;
}

message Contacts
{
    repeated PeopleInfo contacts = 1;
}

2.将写进行修改

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void AddPeopleInfo(contacts2::PeopleInfo* contact)
{
    cout << "---------------新增联系人-------------" << endl;
    cout << "请输入姓名:" << endl;
    string name;
    getline(cin,name);
    contact->set_name(name);

    cout << "请输入联系人年龄" << endl;
    int age;
    cin >> age;
    contact->set_age(age);
    cin.ignore(256,'\n');

    for(int i = 0;;i++)
    {
        cout << "请输入" << i+1 << "个联系人电话: " << endl;
        string phone;
        getline(cin,phone);
        if(phone.empty())
        {
            break;
        }
        contacts2::PeopleInfo_Phone* phone_number = contact->add_phone();
        phone_number->set_number(phone);
        cout << "请输入电话类型(1:移动电话,2:固定电话)" << endl;
        int type;
        cin >> type;
        cin.ignore(256,'\n');
        switch(type)
        {
            case 1:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
                break;
            case 2:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
                break;
            default:
                cout << "输入错误,请重新输入!" << endl;
                break;
        }
    }
    
    cout << "--------------新增联系人成功-------------" << endl;
}

int main()
{
    contacts2::Contacts contacts;
    //读取以及存在的联系人文件
    fstream input("contacts.bin",ios::in|ios::binary);
    if(!input.is_open())
    {
        cout<<"open file failed, create new file!"<<endl;
    }
    else if(!contacts.ParseFromIstream(&input))
    {
        cout<<"parse file failed!"<<endl;
        input.close();
        return -1;
    }
    //向通讯录中添加联系人
    AddPeopleInfo(contacts.add_contacts());
    //将通讯录写入本地文件
    fstream output("contacts.bin",ios::out|ios::binary|ios::trunc);
    if(!output.is_open())
    {
        cout<<"open file failed!"<<endl;
        return -1;
    }
    else if(!contacts.SerializeToOstream(&output))
    {
        cout<<"serialize file failed!"<<endl;
        output.close();
        input.close();
        return -1;
    }
    cout << "write success!" << endl;
    input.close();
    output.close();
    return 0;
}

3.将读进行修改

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void PrintContacts(contacts2::Contacts& contacts) {
    for (int i = 0; i < contacts.contacts_size(); i++) {
        cout << "----------------联系人" << i+1 << "----------------" << endl;
        const contacts2::PeopleInfo& people = contacts.contacts(i);
        cout << "联系人姓名: " << people.name() << endl;
        cout << "联系人年龄: " << people.age() << endl;
        for (int j = 0; j < people.phone_size(); j++) {
            const contacts2::PeopleInfo_Phone& phone = people.phone(j);
            cout << "  联系人电话" << j+1 << ": " << phone.number();
            cout << "  (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
        }
    }
}

int main() {
    contacts2::Contacts contacts;
    // 读取本地已存在的通讯录文件
    fstream input("contacts.bin", ios::in | ios::binary);
    if (!contacts.ParseFromIstream(&input)) {
        cerr << "parse error!" << endl;
        input.close();
        return -1;
    }
    // 打印通讯录列表
    PrintContacts(contacts);
    return 0;
}

四.Any类型

1.介绍

2.设置联系人地址信息

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void AddPeopleInfo(contacts2::PeopleInfo* contact)
{
    cout << "---------------新增联系人-------------" << endl;
    cout << "请输入姓名:" << endl;
    string name;
    getline(cin,name);
    contact->set_name(name);

    cout << "请输入联系人年龄" << endl;
    int age;
    cin >> age;
    contact->set_age(age);
    cin.ignore(256,'\n');

    for(int i = 0;;i++)
    {
        cout << "请输入" << i+1 << "个联系人电话: " << endl;
        string phone;
        getline(cin,phone);
        if(phone.empty())
        {
            break;
        }
        contacts2::PeopleInfo_Phone* phone_number = contact->add_phone();
        phone_number->set_number(phone);
        cout << "请输入电话类型(1:移动电话,2:固定电话)" << endl;
        int type;
        cin >> type;
        cin.ignore(256,'\n');
        switch(type)
        {
            case 1:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
                break;
            case 2:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
                break;
            default:
                cout << "输入错误,请重新输入!" << endl;
                break;
        }
    }

    //新增联系人地址
    contacts2::Address address;
    cout << "请输入家庭住址:" << endl;
    string home_address;
    getline(cin,home_address);
    address.set_home_address(home_address);
    cout << "请输入单位住址:" << endl;
    string unit_address;
    getline(cin,unit_address);
    address.set_unit_address(unit_address);
    contact->mutable_data()->PackFrom(address);
    
    cout << "--------------新增联系人成功-------------" << endl;
}

int main()
{
    contacts2::Contacts contacts;
    //读取以及存在的联系人文件
    fstream input("contacts.bin",ios::in|ios::binary);
    if(!input.is_open())
    {
        cout<<"open file failed, create new file!"<<endl;
    }
    else if(!contacts.ParseFromIstream(&input))
    {
        cout<<"parse file failed!"<<endl;
        input.close();
        return -1;
    }
    //向通讯录中添加联系人
    AddPeopleInfo(contacts.add_contacts());
    //将通讯录写入本地文件
    fstream output("contacts.bin",ios::out|ios::binary|ios::trunc);
    if(!output.is_open())
    {
        cout<<"open file failed!"<<endl;
        return -1;
    }
    else if(!contacts.SerializeToOstream(&output))
    {
        cout<<"serialize file failed!"<<endl;
        output.close();
        input.close();
        return -1;
    }
    cout << "write success!" << endl;
    input.close();
    output.close();
    return 0;
}

3.读取联系人住址信息

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void PrintContacts(contacts2::Contacts& contacts) {
    for (int i = 0; i < contacts.contacts_size(); i++) {
        cout << "----------------联系人" << i+1 << "----------------" << endl;
        const contacts2::PeopleInfo& people = contacts.contacts(i);
        cout << "联系人姓名: " << people.name() << endl;
        cout << "联系人年龄: " << people.age() << endl;
        for (int j = 0; j < people.phone_size(); j++) {
            const contacts2::PeopleInfo_Phone& phone = people.phone(j);
            cout << "  联系人电话" << j+1 << ": " << phone.number();
            cout << "  (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
        }
        if(people.has_data() && people.data().Is<contacts2::Address>())
        {
            contacts2::Address address;
            people.data().UnpackTo(&address);
            if(!address.home_address().empty())
            cout << "  联系人家庭住址: " << address.home_address() << endl;
            if(!address.unit_address().empty())
            cout << "  联系人单位住址: " << address.unit_address() << endl;
        }
    }
}

int main() {
    contacts2::Contacts contacts;
    // 读取本地已存在的通讯录文件
    fstream input("contacts.bin", ios::in | ios::binary);
    if (!contacts.ParseFromIstream(&input)) {
        cerr << "parse error!" << endl;
        input.close();
        return -1;
    }
    // 打印通讯录列表
    PrintContacts(contacts);
    return 0;
}

五.oneof类型

1.讲解oneof类型

2.进行读写文件修改

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void AddPeopleInfo(contacts2::PeopleInfo* contact)
{
    cout << "---------------新增联系人-------------" << endl;
    cout << "请输入姓名:" << endl;
    string name;
    getline(cin,name);
    contact->set_name(name);

    cout << "请输入联系人年龄" << endl;
    int age;
    cin >> age;
    contact->set_age(age);
    cin.ignore(256,'\n');

    for(int i = 0;;i++)
    {
        cout << "请输入" << i+1 << "个联系人电话: " << endl;
        string phone;
        getline(cin,phone);
        if(phone.empty())
        {
            break;
        }
        contacts2::PeopleInfo_Phone* phone_number = contact->add_phone();
        phone_number->set_number(phone);
        cout << "请输入电话类型(1:移动电话,2:固定电话)" << endl;
        int type;
        cin >> type;
        cin.ignore(256,'\n');
        switch(type)
        {
            case 1:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
                break;
            case 2:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
                break;
            default:
                cout << "输入错误,请重新输入!" << endl;
                break;
        }
    }

    //新增联系人地址
    contacts2::Address address;
    cout << "请输入家庭住址:" << endl;
    string home_address;
    getline(cin,home_address);
    address.set_home_address(home_address);
    cout << "请输入单位住址:" << endl;
    string unit_address;
    getline(cin,unit_address);
    address.set_unit_address(unit_address);
    contact->mutable_data()->PackFrom(address);

    cout << "请选择其他联系方式(1:qq,2:微信)" << endl;
    int other_contact;
    cin >> other_contact;
    cin.ignore(256,'\n');
    switch(other_contact)
    {
        case 1:
            {
                cout << "请输入qq号: " << endl;
                string qq;
                getline(cin,qq);
                contact->set_qq(qq);
                break;
            }
        case 2:
            {
                cout << "请输入微信号: " << endl;
                string wechat;
                getline(cin,wechat);
                contact->set_wechat(wechat);
                break;
            }
        default:
            cout << "输入错误,请重新输入!" << endl;
            break;
    }
    
    cout << "--------------新增联系人成功-------------" << endl;
}

int main()
{
    contacts2::Contacts contacts;
    //读取以及存在的联系人文件
    fstream input("contacts.bin",ios::in|ios::binary);
    if(!input.is_open())
    {
        cout<<"open file failed, create new file!"<<endl;
    }
    else if(!contacts.ParseFromIstream(&input))
    {
        cout<<"parse file failed!"<<endl;
        input.close();
        return -1;
    }
    //向通讯录中添加联系人
    AddPeopleInfo(contacts.add_contacts());
    //将通讯录写入本地文件
    fstream output("contacts.bin",ios::out|ios::binary|ios::trunc);
    if(!output.is_open())
    {
        cout<<"open file failed!"<<endl;
        return -1;
    }
    else if(!contacts.SerializeToOstream(&output))
    {
        cout<<"serialize file failed!"<<endl;
        output.close();
        input.close();
        return -1;
    }
    cout << "write success!" << endl;
    input.close();
    output.close();
    return 0;
}
cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void PrintContacts(contacts2::Contacts& contacts) {
    for (int i = 0; i < contacts.contacts_size(); i++) {
        cout << "----------------联系人" << i+1 << "----------------" << endl;
        const contacts2::PeopleInfo& people = contacts.contacts(i);
        cout << "联系人姓名: " << people.name() << endl;
        cout << "联系人年龄: " << people.age() << endl;
        for (int j = 0; j < people.phone_size(); j++) {
            const contacts2::PeopleInfo_Phone& phone = people.phone(j);
            cout << "  联系人电话" << j+1 << ": " << phone.number();
            cout << "  (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
        }
        if(people.has_data() && people.data().Is<contacts2::Address>())
        {
            contacts2::Address address;
            people.data().UnpackTo(&address);
            if(!address.home_address().empty())
            cout << "  联系人家庭住址: " << address.home_address() << endl;
            if(!address.unit_address().empty())
            cout << "  联系人单位住址: " << address.unit_address() << endl;
        }
        switch(people.other_contact_case())
        {
            case contacts2::PeopleInfo::OtherContactCase::kQq:
                cout << "  联系人qq号: " << people.qq() << endl;
                break;
            case contacts2::PeopleInfo::OtherContactCase::kWechat:
                cout << "  联系人微信号: " << people.wechat() << endl;
                break;
            default:
                break;
        }
    }
}

int main() {
    contacts2::Contacts contacts;
    // 读取本地已存在的通讯录文件
    fstream input("contacts.bin", ios::in | ios::binary);
    if (!contacts.ParseFromIstream(&input)) {
        cerr << "parse error!" << endl;
        input.close();
        return -1;
    }
    // 打印通讯录列表
    PrintContacts(contacts);
    return 0;
}

六.map类型

1.使用方法

cpp 复制代码
syntax = "proto3";
package contacts2;

import "google/protobuf/any.proto";

message Address
{
    string home_address = 1;//家庭住址
    string unit_address = 2;//单位地址
}

//定义联系人message
message PeopleInfo
{
    string name = 1; //姓名
    int32 age = 2;   //年龄
    message Phone
    {
        string number = 1;
        enum PhoneType
        {
            MP = 0; //移动电话
            TEL = 1; //固定电话
        }
        PhoneType type = 2;
    }
    repeated Phone phone = 3;
    google.protobuf.Any data = 4;

    oneof other_contact
    {
        string qq = 5; // 不能使用repeated
        string wechat = 6;
    }
    
    map<string,string> remark = 7; //备注信息
}

message Contacts
{
    repeated PeopleInfo contacts = 1;
}

2.读写修改

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void AddPeopleInfo(contacts2::PeopleInfo* contact)
{
    cout << "---------------新增联系人-------------" << endl;
    cout << "请输入姓名:" << endl;
    string name;
    getline(cin,name);
    contact->set_name(name);

    cout << "请输入联系人年龄" << endl;
    int age;
    cin >> age;
    contact->set_age(age);
    cin.ignore(256,'\n');

    for(int i = 0;;i++)
    {
        cout << "请输入" << i+1 << "个联系人电话: " << endl;
        string phone;
        getline(cin,phone);
        if(phone.empty())
        {
            break;
        }
        contacts2::PeopleInfo_Phone* phone_number = contact->add_phone();
        phone_number->set_number(phone);
        cout << "请输入电话类型(1:移动电话,2:固定电话)" << endl;
        int type;
        cin >> type;
        cin.ignore(256,'\n');
        switch(type)
        {
            case 1:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
                break;
            case 2:
                phone_number->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
                break;
            default:
                cout << "输入错误,请重新输入!" << endl;
                break;
        }
    }

    //新增联系人地址
    contacts2::Address address;
    cout << "请输入家庭住址:" << endl;
    string home_address;
    getline(cin,home_address);
    address.set_home_address(home_address);
    cout << "请输入单位住址:" << endl;
    string unit_address;
    getline(cin,unit_address);
    address.set_unit_address(unit_address);
    contact->mutable_data()->PackFrom(address);

    cout << "请选择其他联系方式(1:qq,2:微信)" << endl;
    int other_contact;
    cin >> other_contact;
    cin.ignore(256,'\n');
    switch(other_contact)
    {
        case 1:
            {
                cout << "请输入qq号: " << endl;
                string qq;
                getline(cin,qq);
                contact->set_qq(qq);
                break;
            }
        case 2:
            {
                cout << "请输入微信号: " << endl;
                string wechat;
                getline(cin,wechat);
                contact->set_wechat(wechat);
                break;
            }
        default:
            cout << "输入错误,请重新输入!" << endl;
            break;
    }
    for(int i = 0;; i++)
    {
        cout << "请输入第" << i+1 << "个备注标题(只输入回车完成备注新增): " << endl;
        string remark_key;
        getline(cin,remark_key);
        if(remark_key.empty())
        {
            break;
        }
        cout << "请输入第" << i+1 << "个备注内容: " << endl;
        string remark_value;
        getline(cin,remark_value);
        if(remark_value.empty())
        {
            cout << "输入错误,请重新输入!" << endl;
            continue;
        }
        contact->mutable_remark()->insert({remark_key,remark_value});
    }
    
    cout << "--------------新增联系人成功-------------" << endl;
}

int main()
{
    contacts2::Contacts contacts;
    //读取以及存在的联系人文件
    fstream input("contacts.bin",ios::in|ios::binary);
    if(!input.is_open())
    {
        cout<<"open file failed, create new file!"<<endl;
    }
    else if(!contacts.ParseFromIstream(&input))
    {
        cout<<"parse file failed!"<<endl;
        input.close();
        return -1;
    }
    //向通讯录中添加联系人
    AddPeopleInfo(contacts.add_contacts());
    //将通讯录写入本地文件
    fstream output("contacts.bin",ios::out|ios::binary|ios::trunc);
    if(!output.is_open())
    {
        cout<<"open file failed!"<<endl;
        return -1;
    }
    else if(!contacts.SerializeToOstream(&output))
    {
        cout<<"serialize file failed!"<<endl;
        output.close();
        input.close();
        return -1;
    }
    cout << "write success!" << endl;
    input.close();
    output.close();
    return 0;
}
cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void PrintContacts(contacts2::Contacts& contacts) {
    for (int i = 0; i < contacts.contacts_size(); i++) {
        cout << "----------------联系人" << i+1 << "----------------" << endl;
        const contacts2::PeopleInfo& people = contacts.contacts(i);
        cout << "联系人姓名: " << people.name() << endl;
        cout << "联系人年龄: " << people.age() << endl;
        for (int j = 0; j < people.phone_size(); j++) {
            const contacts2::PeopleInfo_Phone& phone = people.phone(j);
            cout << "  联系人电话" << j+1 << ": " << phone.number();
            cout << "  (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
        }
        if(people.has_data() && people.data().Is<contacts2::Address>())
        {
            contacts2::Address address;
            people.data().UnpackTo(&address);
            if(!address.home_address().empty())
            cout << "  联系人家庭住址: " << address.home_address() << endl;
            if(!address.unit_address().empty())
            cout << "  联系人单位住址: " << address.unit_address() << endl;
        }
        switch(people.other_contact_case())
        {
            case contacts2::PeopleInfo::OtherContactCase::kQq:
                cout << "  联系人qq号: " << people.qq() << endl;
                break;
            case contacts2::PeopleInfo::OtherContactCase::kWechat:
                cout << "  联系人微信号: " << people.wechat() << endl;
                break;
            default:
                break;
        }
        if(people.remark_size() > 0)
        {
            cout << "  联系人备注: " << endl;
            for (const auto& remark : people.remark()) {
                cout << "    " << remark.first << ": " << remark.second << endl;
            }
        }
    }
}

int main() {
    contacts2::Contacts contacts;
    // 读取本地已存在的通讯录文件
    fstream input("contacts.bin", ios::in | ios::binary);
    if (!contacts.ParseFromIstream(&input)) {
        cerr << "parse error!" << endl;
        input.close();
        return -1;
    }
    // 打印通讯录列表
    PrintContacts(contacts);
    return 0;
}

七.默认值

八.更新消息

1.更新规则

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void AddPeopleInfo(s_contacts::PeopleInfo* contact)
{
    cout << "---------------新增联系人-------------" << endl;
    cout << "请输入姓名:" << endl;
    string name;
    getline(cin,name);
    contact->set_name(name);

    cout << "请输入联系人年龄" << endl;
    int age;
    cin >> age;
    contact->set_age(age);
    cin.ignore(256,'\n');

    for(int i = 0;;i++)
    {
        cout << "请输入" << i+1 << "个联系人电话: " << endl;
        string phone;
        getline(cin,phone);
        if(phone.empty())
        {
            break;
        }
        s_contacts::PeopleInfo_Phone* phone_number = contact->add_phone();
        phone_number->set_number(phone);
    }
    
    cout << "--------------新增联系人成功-------------" << endl;
}

int main()
{
    s_contacts::Contacts contacts;
    //读取以及存在的联系人文件
    fstream input("../contacts.bin",ios::in|ios::binary);
    if(!input.is_open())
    {
        cout<<"open file failed, create new file!"<<endl;
    }
    else if(!contacts.ParseFromIstream(&input))
    {
        cout<<"parse file failed!"<<endl;
        input.close();
        return -1;
    }
    //向通讯录中添加联系人a
    AddPeopleInfo(contacts.add_contacts());
    //将通讯录写入本地文件
    fstream output("../contacts.bin",ios::out|ios::binary|ios::trunc);
    if(!output.is_open())
    {
        cout<<"open file failed!"<<endl;
        return -1;
    }
    else if(!contacts.SerializeToOstream(&output))
    {
        cout<<"serialize file failed!"<<endl;
        output.close();
        input.close();
        return -1;
    }
    cout << "write success!" << endl;
    input.close();
    output.close();
    return 0;
}
cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void PrintContacts(c_contacts::Contacts& contacts) {
    for (int i = 0; i < contacts.contacts_size(); i++) {
        cout << "----------------联系人" << i+1 << "----------------" << endl;
        const c_contacts::PeopleInfo& people = contacts.contacts(i);
        cout << "联系人姓名: " << people.name() << endl;
        cout << "联系人年龄: " << people.age() << endl;
        for (int j = 0; j < people.phone_size(); j++) {
            const c_contacts::PeopleInfo_Phone& phone = people.phone(j);
            cout << "  联系人电话" << j+1 << ": " << phone.number() << endl;
        }
    }
}

int main() {
    c_contacts::Contacts contacts;
    // 读取本地已存在的通讯录文件
    fstream input("../contacts.bin", ios::in | ios::binary);
    if (!contacts.ParseFromIstream(&input)) {
        cerr << "parse error!" << endl;
        input.close();
        return -1;
    }
    // 打印通讯录列表
    PrintContacts(contacts);
    input.close();
    return 0;
}
cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;

void AddPeopleInfo(s_contacts::PeopleInfo* contact)
{
    cout << "---------------新增联系人-------------" << endl;
    cout << "请输入姓名:" << endl;
    string name;
    getline(cin,name);
    contact->set_name(name);

    // cout << "请输入联系人年龄" << endl;
    // int age;
    // cin >> age;
    // contact->set_age(age);
    // cin.ignore(256,'\n');

    cout << "请输入联系人出生日期(yyyyMMdd)" << endl;
    int birthday;
    cin >> birthday;
    contact->set_birthday(birthday);
    cin.ignore(256,'\n');

    for(int i = 0;;i++)
    {
        cout << "请输入" << i+1 << "个联系人电话: " << endl;
        string phone;
        getline(cin,phone);
        if(phone.empty())
        {
            break;
        }
        s_contacts::PeopleInfo_Phone* phone_number = contact->add_phone();
        phone_number->set_number(phone);
    }
    
    cout << "--------------新增联系人成功-------------" << endl;
}

int main()
{
    s_contacts::Contacts contacts;
    //读取以及存在的联系人文件
    fstream input("../contacts.bin",ios::in|ios::binary);
    if(!input.is_open())
    {
        cout<<"open file failed, create new file!"<<endl;
    }
    else if(!contacts.ParseFromIstream(&input))
    {
        cout<<"parse file failed!"<<endl;
        input.close();
        return -1;
    }
    //向通讯录中添加联系人a
    AddPeopleInfo(contacts.add_contacts());
    //将通讯录写入本地文件
    fstream output("../contacts.bin",ios::out|ios::binary|ios::trunc);
    if(!output.is_open())
    {
        cout<<"open file failed!"<<endl;
        return -1;
    }
    else if(!contacts.SerializeToOstream(&output))
    {
        cout<<"serialize file failed!"<<endl;
        output.close();
        input.close();
        return -1;
    }
    cout << "write success!" << endl;
    input.close();
    output.close();
    return 0;
}

然后,我们不对client进行更改

这不就错误了吗?

那怎么办呢? --- 使用 reserved 字段

2.保留字段reserved

cpp 复制代码
syntax = "proto3";
package s_contacts;

//定义联系人message
message PeopleInfo
{
    reserved 2,10,11,100 to 200;
    reserved "age";
    
    string name = 1; //姓名
    // int32 age = 2;   //年龄
    int32 birthday = 4;
    message Phone
    {
        string number = 1;
    }
    repeated Phone phone = 3;
}

message Contacts
{
    repeated PeopleInfo contacts = 1;
}

3.未知字段

a.未知字段从哪获取

b.打印未知字段

cpp 复制代码
#include <iostream>
#include <fstream>
#include "contacts.pb.h"

using namespace std;
using namespace c_contacts;
using namespace google::protobuf;

void PrintContacts(c_contacts::Contacts& contacts) {
    for (int i = 0; i < contacts.contacts_size(); i++) {
        cout << "----------------联系人" << i+1 << "----------------" << endl;
        const c_contacts::PeopleInfo& people = contacts.contacts(i);
        cout << "联系人姓名: " << people.name() << endl;
        cout << "联系人年龄: " << people.age() << endl;
        for (int j = 0; j < people.phone_size(); j++) {
            const c_contacts::PeopleInfo_Phone& phone = people.phone(j);
            cout << "  联系人电话" << j+1 << ": " << phone.number() << endl;
        }
        const Reflection* reflection = PeopleInfo::GetReflection();
        const UnknownFieldSet& unknown_fields = reflection->GetUnknownFields(people);
        for(int j = 0;j<unknown_fields.field_count();j++)
        {
            const UnknownField& field = unknown_fields.field(j);
            cout << "未知字段" << j+1 << ": " << " 编号: " << field.number() << endl;
            switch(field.type())
            {
                case UnknownField::Type::TYPE_VARINT:
                    cout << "  数据: " << field.varint() << endl;
                    break;
                case UnknownField::Type::TYPE_FIXED64:
                    cout << "  数据: " << field.fixed64() << endl;
                    break;
                case UnknownField::Type::TYPE_LENGTH_DELIMITED:
                    cout << "  数据: " << field.length_delimited() << endl;
                    break;
                default:
                    cout << "  未知数据类型" << endl;
                    break;
            }
        }
    }
}

int main() {
    c_contacts::Contacts contacts;
    // 读取本地已存在的通讯录文件
    fstream input("../contacts.bin", ios::in | ios::binary);
    if (!contacts.ParseFromIstream(&input)) {
        cerr << "parse error!" << endl;
        input.close();
        return -1;
    }
    // 打印通讯录列表
    PrintContacts(contacts);
    input.close();
    return 0;
}

c.前后兼容性

九.option选项

1.选项分类

2.常用选项列举

3.设置自定义选项

有兴趣可以自己了解一下

相关推荐
Arciab6 小时前
C++ 学习_基础知识
c++·学习
oioihoii6 小时前
C++ 多线程开发:从零开始的完整指南
开发语言·c++
曼巴UE56 小时前
UE 运行时编辑效果。Gizom使用增强输入改写
c++·ue5
是有头发的程序猿6 小时前
1688数据采集:官方API与网页爬虫实战指南
开发语言·c++·爬虫
霍田煜熙6 小时前
C++ 部署小型图书管理系统
开发语言·c++·算法
@小码农7 小时前
2025年厦门市小学生信息学竞赛C++(初赛)真题-附答案
开发语言·c++·python·算法·蓝桥杯
闻缺陷则喜何志丹7 小时前
【计算几何】凸多变形的定义
c++·数学·计算几何·凸多边形
zore_c7 小时前
【C语言】Win 32 API——一部分内容详解!!!
c语言·开发语言·c++·经验分享·笔记
郝学胜-神的一滴7 小时前
Linux线程编程:从原理到实践
linux·服务器·开发语言·c++·程序人生·设计模式·软件工程