英文:
Need help upon using serialization without classes in C++ since I didn't yet begin object oriented programming. I have an assignment. Please help me
问题
我没学过在C++中使用类,专注于非面向对象编程。
因此我遇到了一种情况,我需要确保我可以序列化向量和其他基本数据类型,以便我可以使用Boost库恢复变量及其值。我尝试了前几天有人发的帖子,并尝试在我的机器上编译他的代码,但是它一直说未定义引用(同时命名了多个文件夹)。我在Visual Studio中正确链接了Boost库。
我试图链接Boost库,以前它们在我的Visual Studio代码中没有被识别,但经过一些配置后,它们现在被正确识别了,下面是我的launch.json配置:
{
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "输入程序名称,例如 ${workspaceFolder}/a.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/path/to/gdb",
"setupCommands": [
{
"description": "启用对gdb的漂亮打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
对于我的settings.json:
{
"C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.cCompilerPath": "C:/msys64/mingw64/bin/gcc.exe",
"C_Cpp_Runner.cppCompilerPath": "C:/msys64/mingw64/bin/g++.exe",
"C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wconversion",
"-Wnull-dereference",
"-Wsign-conversion"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [
"\"-Lboost\""
],
"C_Cpp_Runner.includePaths": [
"C:\\msys64\\mingw64\\include\\boost"
],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false
}
对于我的tasks.json:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:/msys64/mingw64/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\${fileBasenameNoExtension}.exe",
"-Lboost"
],
"options": {
"cwd": "C:/msys64/mingw64/bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Debugger生成的任务。"
}
],
"version": "2.0.0"
}
英文:
I didn't learn working with classes in C++, focusing on non object oriented programming.
So I ran into a situation where I need to make sure I can serialize vectors and other primitive data types, so I can revive the variables and their value with the boost libraries, I tried the post someone did the other day and tried to compile his code on my machine however it keep saying undefined reference (while naming multiple folders) I linked the boost libraries in visual studio fine .
[text](enter image description here)
enter image description here
I tried to link the boost libraries , before they weren't recognized in my visual studio code but after some configurations they are well reconized now and no red undeline appear under them which is a good thing.
Here are my launch.json configurations:
{
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "enter program name, for example ${workspaceFolder}/a.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/path/to/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
For my settings.json
{
"C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.cCompilerPath": "C:/msys64/mingw64/bin/gcc.exe",
"C_Cpp_Runner.cppCompilerPath": "C:/msys64/mingw64/bin/g++.exe",
"C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wconversion",
"-Wnull-dereference",
"-Wsign-conversion"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [
"\"-Lboost\""
],
"C_Cpp_Runner.includePaths": [
"C:\\msys64\\mingw64\\include\\boost"
],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false
}
for my tasks.json
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:/msys64/mingw64/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\${fileBasenameNoExtension}.exe",
"-Lboost"
],
"options": {
"cwd": "C:/msys64/mingw64/bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
答案1
得分: 3
以下是已翻译的内容:
Boost Serialization 是100%面向对象的,所以你可能不应该使用它。
此外,std::vector
的实例化不是原始类型。
为什么不编写自己的例程?以下是100%过程化且无麸质的:
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
std::string serialize(std::vector<int> v) {
std::ostringstream oss;
oss << v.size() << "\n";
for (auto const& el : v)
oss << " " << el;
oss << std::endl;
return oss.str();
}
std::string serialize(std::vector<std::string> v) {
std::ostringstream oss;
oss << v.size() << "\n";
for (auto const& el : v)
oss << " " << quoted(el);
oss << std::endl;
return oss.str();
}
bool deserialize(std::istream& is, std::vector<int>& into) {
size_t n;
for (is >> n; is && n; --n) {
into.emplace_back();
is >> into.back();
}
return is.good() || is.eof();
}
bool deserialize(std::istream& is, std::vector<std::string>& into) {
size_t n;
for (is >> n; is && n; --n) {
into.emplace_back();
is >> quoted(into.back());
}
return is.good() || is.eof();
}
int main() {
// 将两个不同大小和类型的向量保存到一个字符串中(你可以将其写入文件)
std::string text = serialize({1, 2, 3, 4}) + serialize({"one", "two deux", "hello \"world!\""});
// 读取它
std::vector<int> ints;
std::vector<std::string> strings;
{
std::istringstream is(text);
bool ok = deserialize(is, ints) && deserialize(is, strings);
std::cout << "Result: " << std::boolalpha << ok << "\n";
}
std::cout << "ints: (" << ints.size() << ") ";
for (auto i : ints)
std::cout << " " << i;
std::cout << "\nstrings: (" << strings.size() << ") ";
for (auto s : strings)
std::cout << " " << quoted(s);
}
输出如下:
Result: true
ints: (4) 1 2 3 4
strings: (3) "one" "two deux" "hello \"world!\""
奖励
关于未定义符号的引用:什么是未定义引用(未解析的外部符号)错误,如何修复?
英文:
Boost Serialization is 100% object oriented, so you should probably not be using it.
Besides, std::vector
instantiations are not primitive types.
Why not write your own routine? The following is 100% procedural and gluten-free:
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
std::string serialize(std::vector<int> v) {
std::ostringstream oss;
oss << v.size() << "\n";
for (auto const& el : v)
oss << " " << el;
oss << std::endl;
return oss.str();
}
std::string serialize(std::vector<std::string> v) {
std::ostringstream oss;
oss << v.size() << "\n";
for (auto const& el : v)
oss << " " << quoted(el);
oss << std::endl;
return oss.str();
}
bool deserialize(std::istream& is, std::vector<int>& into) {
size_t n;
for (is >> n; is && n; --n) {
into.emplace_back();
is >> into.back();
}
return is.good() || is.eof();
}
bool deserialize(std::istream& is, std::vector<std::string>& into) {
size_t n;
for (is >> n; is && n; --n) {
into.emplace_back();
is >> quoted(into.back());
}
return is.good() || is.eof();
}
int main() {
// save two vectors of different sizes and types into one string
// (you could write that to a file)
std::string text = serialize({1, 2, 3, 4}) + serialize({"one", "two deux", "hello \"world\"!"});
// read it back
std::vector<int> ints;
std::vector<std::string> strings;
{
std::istringstream is(text);
bool ok = deserialize(is, ints) && deserialize(is, strings);
std::cout << "Result: " << std::boolalpha << ok << "\n";
}
std::cout << "ints: (" << ints.size() << ") ";
for (auto i : ints)
std::cout << " " << i;
std::cout << "\nstrings: (" << strings.size() << ") ";
for (auto s : strings)
std::cout << " " << quoted(s);
}
Prints the expectable
Result: true
ints: (4) 1 2 3 4
strings: (3) "one" "two deux" "hello \"world\"!"
BONUS
Regarding references to undefined symbols: https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论