聚划算网站建设分析,wordpress主题xiu,网页设计与网站建设文档,wordpress主题微信验证码protobuf的简单使用#xff08;通讯录例子#xff09; .proto文件的编写保留字段字段唯一编号protobuf的类型enum类型Any类型oneof类型map类型完整通讯录代码.proto文件write文件read文件运行结果 .proto文件的编写
syntax用于指定protobuf的语法#xff1b;package当.prot… protobuf的简单使用通讯录例子 .proto文件的编写保留字段字段唯一编号protobuf的类型enum类型Any类型oneof类型map类型完整通讯录代码.proto文件write文件read文件运行结果 .proto文件的编写
syntax用于指定protobuf的语法package当.proto文件编译后再*.pb.h文件中会形成一个命名空间。message消息名称当.proto文件编译后再*.pb.h文件中会形成一个类。
保留字段
可以看到每一个属性后面会有一个数字编号可以看成属性的唯一标识用来在消息的二进制格式中标识属性同一个message域里面不可以使用冲突。定义了就不能修改了若是想删除就要将编号添加进reserved保留字段并且该字段不可继续使用。例如
message PeopleInfo{//可以单个指定保留字段也可指定一个范围的保留字段// 13 to 20 包含13和20。reserved 10, 11, 13 to 20;// 也可指明字段名reserved gender;string field1 10;string field2 11;string field3 15;string gender 9;string name 1;uint32 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;string wechat 6;}mapstring, string remark 7;
}如上可以看到定义了保留字段编译后如下 表示保留字段不可继续使用。
字段唯一编号 另外字段唯一编号范围为1 ~ 5368709112^29-1)其中19000 ~ 19999不可用。如果使用了就会告警。 指定字段唯一编号时对于使用频繁的字段将其唯一编号设置为1 ~ 15 因为1 ~ 15的字段编号只需要一个字节进行编码16~2047以内的需要2个字节。
protobuf的类型 .proto Type字段是.proto文件中的字段类型 C Type是.proto文件编译后形成的*.pb.h和 *.pb.c文件中的c对应类型。
enum类型
enum类型可以定义在消息体内也可以定义在消息体外。枚举的常量值在32整数范围内。0值常量必须存在且要作为第一个元素。 同级也就是同一个作用域中各个枚举类型中不能定义相同枚举名称
Any类型 any类型可以理解为泛型类型可以在any中存储任意数据类型any类型也可以用repeated修饰。 在安装protobuf时include目录下包含了google定义好的.proto文件在使用any类型时需要引入any文件使用import即可。如 import google/protobuf/any.proto; 定义any类型时只需使用google.protobuf.Any 当做类型名来定义即可具体的任意类型和any类型的绑定不在.proto文件中编码。 例如 .proto文件中希望将Address类型转换成any类型
message Address{string home_address 1;string unit_address 2;
}
message PeopleInfo{google.protobuf.Any data 4;
}上面的代码为部分截取。 在进行序列化的.cc文件中可以这样编写
Address address;
cout 请输入家庭地址;
string home_address;
getline(cin, home_address);
cout 请输入单位地址;
string unit_address;
getline(cin, unit_address);address.set_home_address(home_address);
address.set_unit_address(unit_address);// 使用mutable_方法会开辟空间并且返回一个any指针
// people_info_ptr是PeopleInfo的指针.
google::protobuf::Any *data people_info_ptr-mutable_data();
PackFrom可以将任意类型转换为any类型。
data-PackFrom(address);使⽤ PackFrom() ⽅法可以将任意消息类型转为 Any 类型。使⽤ UnpackTo() ⽅法可以将 Any 类型转回之前设置的任意消息类型使⽤ Is() ⽅法可以⽤来判断存放的消息类型是否为 typename T。 oneof类型 顾名思义就是在众多类型中选择一个类型进行使用。 例如
oneof other_contact{string qq 5;string wechat 6;}oneof中类型的唯一编号不能和other_contact所在的作用域的编号起冲突要有唯一性。oneof中不能使用repeated。在设置oneof中的值的时候如果多次进行设置值那么只会保留最后一次设置的值。获取当前设置了哪一个字段使用_case方法。 由于多次进行设置值那么只会保留最后一次设置的值。这一特性那么我们在设置oneof值的时候
cout 选择一个其他联系方式1,QQ号 2, 微信号: ;int other_contact;cin other_contact;cin.ignore(256, \n);if(1 other_contact){cout 请输入QQ号;string qq;getline(cin, qq);people_info_ptr-set_qq(qq);}else if(2 other_contact){cout 请输入微信号 ;string wechat;getline(cin, wechat);people_info_ptr-set_wechat(wechat);}else{cout 非法选择该选项设置失败。 endl;}当我们在读取的时候
switch(people.other_contact_case()){case PeopleInfo::OtherContactCase::kQq:cout qq号 people.qq() endl;break;case PeopleInfo::OtherContactCase::kWechat:cout 微信号 people.wechat() endl;break;}map类型 mapkey_type, value_type map_field N; 跟c的map差不多用于key_type和value_type的关系映射。
key_type是除了float和bytes类型以外的任意标量类型。value_type可以是任意类型。map不可以用repeated修饰。map存入的元素是无序的。
//write:
for(int i 1; ; i){cout 请输入备注 i 标题只输入回车完成备注新增: ;string remark_key;getline(cin, remark_key);if(remark_key.empty()) break;cout 请输入备注 i 内容;string remark_value;getline(cin, remark_value);people_info_ptr-mutable_remark()-insert({remark_key, remark_value});}// read:
if(people.remark_size()){cout 备注信息 endl;}for(auto it people.remark().cbegin(); it ! people.remark().cend(); it){cout it-first : it-second endl;}
完整通讯录代码
.proto文件
syntax proto3;
package contacts;
import google/protobuf/any.proto;message Address{string home_address 1;string unit_address 2;
}message PeopleInfo{string name 1;uint32 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;string wechat 6;}mapstring, string remark 7;
}message Contacts{repeated PeopleInfo contacts 1;
}
write文件
#include iostream
#include fstream
#include contacts.pb.husing namespace std;
using namespace contacts;
void AddPeopleInfo(PeopleInfo *people_info_ptr)
{cout ---------------新增联系人------------------- endl;cout 请输入联系人姓名;string name;getline(cin, name);people_info_ptr-set_name(name);cout 请输入联系人年龄;int age;cin age;people_info_ptr-set_age(age);cin.ignore(256, \n);for(int i 1; ; i){cout 请输入联系人电话 i (只输入回车完成电话新增): ;string number;getline(cin, number);if(number.empty()){break;}PeopleInfo_Phone *phone people_info_ptr-add_phone();phone-set_number(number);cout 选择此电话类型1, 移动电话 2, 固定电话: ;int type;cin type;cin.ignore(256, \n);switch(type){case 1:phone-set_type(PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);break;case 2:phone-set_type(PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);break;default:cout 非法选择使用默认值 endl;break;}}Address address;cout 请输入联系人家庭地址;string home_address;getline(cin, home_address);address.set_home_address(home_address);cout 请输入联系人单位地址;string unit_address;getline(cin, unit_address);address.set_unit_address(unit_address);google::protobuf::Any *data people_info_ptr-mutable_data();data-PackFrom(address);cout 选择一个其他联系方式1,QQ号 2, 微信号: ;int other_contact;cin other_contact;cin.ignore(256, \n);if(1 other_contact){cout 请输入QQ号;string qq;getline(cin, qq);people_info_ptr-set_qq(qq);}else if(2 other_contact){cout 请输入微信号 ;string wechat;getline(cin, wechat);people_info_ptr-set_wechat(wechat);}else{cout 非法选择该选项设置失败。 endl;}for(int i 1; ; i){cout 请输入备注 i 标题只输入回车完成备注新增: ;string remark_key;getline(cin, remark_key);if(remark_key.empty()) break;cout 请输入备注 i 内容;string remark_value;getline(cin, remark_value);people_info_ptr-mutable_remark()-insert({remark_key, remark_value});}cout ---------------添加联系人成功---------------- endl;}
int main()
{Contacts contacts;fstream input(./contacts.bin, ios::in | ios::binary);if(!input){cerr contacts.bin file no found endl;return -1;}else if(!contacts.ParseFromIstream(input)){cerr Failed to parse contacts endl;return -1;}AddPeopleInfo(contacts.add_contacts());fstream output(./contacts.bin, ios::out | ios::trunc | ios::binary);if(!contacts.SerializeToOstream(output)){cerr Failed to write contacts. endl;input.close();output.close();return -1;}input.close();output.close();return 0;
}read文件
#include iostream
#include fstream
#include contacts.pb.husing namespace std;
using namespace contacts;void PrintContacts(const Contacts contacts)
{for(int i 0; i contacts.contacts_size(); i){const PeopleInfo people contacts.contacts(i);cout -----------------联系人 i1 --------------------- endl;cout 姓名 people.name() endl;cout 年龄 people.age() endl;int j 0; for(const PeopleInfo_Phone phone : people.phone()){cout 电话 j phone.number() ;cout ( phone.PhoneType_Name(phone.type()) ) endl;}if(people.has_data() people.data().IsAddress()){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 PeopleInfo::OtherContactCase::kQq:cout qq号 people.qq() endl;break;case PeopleInfo::OtherContactCase::kWechat:cout 微信号 people.wechat() endl;break;}if(people.remark_size()){cout 备注信息 endl;}for(auto it people.remark().cbegin(); it ! people.remark().cend(); it){cout it-first : it-second endl;}}
}
int main()
{Contacts contacts;fstream input(contacts.bin, ios::in | ios::binary);if(!contacts.ParseFromIstream(input)){cerr Failed to parse contacts. endl;return -1;}PrintContacts(contacts);input.close();google::protobuf::ShutdownProtobufLibrary();return 0;
}
运行结果 ./write ./read 新人创作不易你的点赞和关注都是对我莫大的鼓励再次感谢您的观看。