C++ 有文本输出的protobuf示例吗?
我想使用protobuf并以文本格式创建序列化输出文件,以进行测试和替换json。我自己不知道怎么写,我正在寻找例子。 这是关于二进制输出的一个:C++ 有文本输出的protobuf示例吗?,c++,protocol-buffers,C++,Protocol Buffers,我想使用protobuf并以文本格式创建序列化输出文件,以进行测试和替换json。我自己不知道怎么写,我正在寻找例子。 这是关于二进制输出的一个: #include <iostream> #include <fstream> #include <string> #include "addressbook.pb.h" using namespace std; // This function fills in a Person message based on
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"
using namespace std;
// This function fills in a Person message based on user input.
void PromptForAddress(tutorial::Person* person) {
cout << "Enter person ID number: ";
int id;
cin >> id;
person->set_id(id);
cin.ignore(256, '\n');
cout << "Enter name: ";
getline(cin, *person->mutable_name());
cout << "Enter email address (blank for none): ";
string email;
getline(cin, email);
if (!email.empty()) {
person->set_email(email);
}
while (true) {
cout << "Enter a phone number (or leave blank to finish): ";
string number;
getline(cin, number);
if (number.empty()) {
break;
}
tutorial::Person::PhoneNumber* phone_number = person->add_phones();
phone_number->set_number(number);
cout << "Is this a mobile, home, or work phone? ";
string type;
getline(cin, type);
if (type == "mobile") {
phone_number->set_type(tutorial::Person::MOBILE);
} else if (type == "home") {
phone_number->set_type(tutorial::Person::HOME);
} else if (type == "work") {
phone_number->set_type(tutorial::Person::WORK);
} else {
cout << "Unknown phone type. Using default." << endl;
}
}
}
// Main function: Reads the entire address book from a file,
// adds one person based on user input, then writes it back out to the same
// file.
int main(int argc, char* argv[]) {
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book;
{
// Read the existing address book.
fstream input(argv[1], ios::in | ios::binary);
if (!input) {
cout << argv[1] << ": File not found. Creating a new file." << endl;
} else if (!address_book.ParseFromIstream(&input)) {
cerr << "Failed to parse address book." << endl;
return -1;
}
}
// Add an address.
PromptForAddress(address_book.add_people());
{
// Write the new address book back to disk.
fstream output(argv[1], ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
cerr << "Failed to write address book." << endl;
return -1;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
#包括
#包括
#包括
#包括“addressbook.pb.h”
使用名称空间std;
//此函数根据用户输入填写个人消息。
作废PromptForAddress(教程::个人*个人){
cout>id;
人员->设置_id(id);
cin.ignore(256,“\n”);
不能更改名称();
无法设置电子邮件(电子邮件);
}
while(true){
无法添加电话();
电话号码->设置电话号码(号码);
无法设置_类型(教程::个人::手机);
}else if(类型==“home”){
电话号码->设置类型(教程::个人::家庭);
}否则如果(类型=“工作”){
电话号码->设置类型(教程::人员::工作);
}否则{
cout此代码将protobuf消息序列化为JSON,并将JSON反序列化为protobuf消息
这是直接从生产代码中提取的(我拥有并特此授予您使用许可证,但请相信我)
这与protobuf 3相关联
标题:
struct pretty\u json\u类型{
void操作符()(google::protobuf::util::JsonOptions&opts)常量{
opts.add_whitespace=true;
}
};
静态constexpr pretty_json_类型pretty_json{};
struct compact_json_类型{
void操作符()(google::protobuf::util::JsonOptions&opts)常量{
opts.add_whitespace=false;
}
};
静态constexpr compact_json_type compact_json{};
结构包含默认值类型{
void操作符()(google::protobuf::util::JsonOptions&opts)常量{
opts.always\u print\u primitive\u fields=true;
}
};
静态constexpr include_defaults_type include_defaults{};
模板
自动json_选项(选项&&…选项)
{
google::protobuf::util::JsonOptions选项;
使用expand=int[];
空(展开){
0,
((选项(opts)),0)。。。
});
返回选项;
}
std::string as_json(const google::protobuf::Message&msg,
google::protobuf::util::JsonOptions opts=json\u options(pretty\u json,
包括);;
std::string as_json(const google::protobuf::Message*msg,
google::protobuf::util::JsonOptions opts=json\u options(pretty\u json,
包括);;
google::protobuf::Message&from_json(google::protobuf::Message&msg,
const char*首先,
标准:尺寸(t尺寸);
内联
decltype(自动)来自_json(google::protobuf::Message&msg),
const std::string和json)
{
从_json返回(msg,json.data(),json.length());
}
实施
std::string as_json(const google::protobuf::Message&msg,
google::protobuf::util::JsonOptions(可选)
{
名称空间pb=google::protobuf;
名称空间pbu=google::protobuf::util;
自动缓冲区=msg.SerializeAsString();
std::字符串结果;
pb::io::ArrayInputStream zistream(buffer.data(),buffer.size());
自动解析器=标准::唯一\u ptr{
pbu::NewTypeResolverForDescriptorPool(“”,
pb::DescriptorPool::生成的_池()
};
auto status=google::protobuf::util::BinaryToJsonString(resolver.get(),
“/”+msg.GetDescriptor()->全名(),
缓冲器
std::addressof(结果),
选择);
如果(!status.ok())
{
std::ostringstream ss;
ss全名(),
zistream.get(),zostream.get();
zistream.reset();
zostream.reset();
if(msg.ParseFromString(二进制缓冲区))
{
返回味精;
}
抛出std::runtime_错误(“无效消息”);
}
调试字符串输出保证为有效的文本序列化格式,但不关心协议消息是否实际有效:
std::string s = msg.DebugString(); // or ShortDebugString
如果要验证,请使用:
#包括
if(std::string s;google::protobuf::TextFormat::PrintToString(msg,&s)){
std::cout要在三行代码中将消息转换为JSON,请执行以下操作-
#include <google/protobuf/util/json_util.h>
static std::string ProtoToJson(const google::protobuf::Message& proto)
{
std::string json;
google::protobuf::util::MessageToJsonString(proto, &json);
return json;
}
#包括
静态std::stringprotojson(constgoogle::protobuf::Message&proto)
{
std::stringjson;
google::protobuf::util::MessageToJsonString(proto,&json);
返回json;
}
尝试地址簿.ShortDebugString()
或TextFormat::PrintToString(地址簿,&str)
。我包含了#包含
,并使用了指定的行。我得到以下错误:错误:未声明“TextFormat”
可能是google::protobuf::TextFormat
或类似的。
std::string s = msg.DebugString(); // or ShortDebugString
#include <google/protobuf/text_format.h>
if (std::string s; google::protobuf::TextFormat::PrintToString(msg, &s)) {
std::cout << "Your message: " << s;
} else {
std::cerr << "Message not valid (partial content: "
<< msg.ShortDebugString() << ")\n";
}
#include <google/protobuf/util/json_util.h>
static std::string ProtoToJson(const google::protobuf::Message& proto)
{
std::string json;
google::protobuf::util::MessageToJsonString(proto, &json);
return json;
}