I have written a code where i am writing a map in a binary file and than reading it using boost memory mapping, but whenever i display the result it is not correct it only shows value as
1852795252
. what should i do? Here's my code:
#include <iostream>
#include <vector>
#include <utility>
#include <fstream>
#include <utility>
#include <fstream>
#include <iterator>
#include <string>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <fstream>
#include <boost/serialization/map.hpp>
using namespace boost::archive;
using namespace boost::interprocess;
void save()
{
{
std::ofstream file{"archive1.bin"};
text_oarchive oa{file};
std::map<int,int> m;
m[3] = 9;
oa << m;
}
}
void load()
{
file_mapping fm("archive1.bin", read_only);
mapped_region region(fm, read_only);
int * m = (int *)region.get_address();
std::cout<<m[3]<<std::endl;
}
int main()
{
save();
load();
}
The problem is that you are not writing to archive1.bin what you think you are writing. This can be demonstrated by adding the lines:
text_oarchive oa2 {std::cout};
oa2 << m;
at the end of function save, and when you do this you see:
22 serialization::archive 17 0 0 1 0 0 0 3 9
printed to stdout.
To clarify further, change the last line of function load to:
std::cout << std::hex << m[3] << std::endl;
and then you see:
6e6f6974
which is ASCII noit, i.e. the fourth integer in archive1.bin.
All of which is a long-winded way of saying what john says in his comment above. You should read a boost archive using the approved serialisation functions.
Live demo.
Related
Since a few days I was trying to get a C++ code that converts the Turkish I character to lowercase ı correctly on VS2022 on Windows.
As I understand, Turkish I has the same Unicode as regular Latin I, thus, I need to define the locale as Turkish before converting, I used the following code:
#include <clocale>
#include <cwctype>
#include <fstream>
#include <iostream>
#include <locale>
#include <string>
int main() {
std::wstring input_str = L"I";
std::setlocale(LC_ALL, "tr_TR.UTF-8"); // This should impact std::towlower
std::locale loc("tr_TR.UTF-8");
std::wofstream output_file("lowercase_turkish.txt");
output_file.imbue(loc);
for (wchar_t& c : input_str) {
c = std::towlower(c);
}
output_file << input_str << std::endl;
output_file.close();
}
It worked fine on Linux, outputing ı, but didn't work correctly on Windows and it outputed i inplace of ı.
After some research I think it is a bug in Windows unicode/ascii mapping, so I went to an alternative solution, using an external library called boost, here is my code:
#include <boost/algorithm/string.hpp>
#include <string>
#include <locale>
#include <iostream>
#include <fstream>
using namespace std;
using namespace boost::algorithm;
int main()
{
std::string s = "I";
std::locale::global(std::locale{ "Turkish" });
to_lower(s);
ofstream outfile("output.txt");
outfile << s << endl;
outfile.close();
return 0;
}
again, outputing i inplace of ı. also using to_lower_copy outputs the same.
I am trying to use boost file_lock to control two processes. I have process 1 obtaining a lock and then sleeping:
#include <boost/interprocess/sync/file_lock.hpp>
#include <fstream>
#include <chrono>
#include <thread>
int main()
{
std::string lock_path = "lockfile";
std::ofstream stream(lock_path, std::ios::app);
boost::interprocess::file_lock lock(lock_path.c_str());
if (lock.try_lock())
{
std::this_thread::sleep_for(std::chrono::seconds(30));
}
return 0;
}
while this process is sleeping, I will run a second process which tries to obtain the lock as well.
#include <boost/interprocess/sync/file_lock.hpp>
#include <iostream>
int main()
{
boost::interprocess::file_lock lock("lockfile");
if (lock.try_lock())
{
std::cout << "got here" << std::endl;
}
return 0;
}
I am expecting the cout statement on the second process not to print because the file is already locked by another process but it does print. What am I missing here? is file_lock not supposed to be used this way?
The best explanation I can think of is when your processes accidentally refer to different files. This might occur when
the current working directories are not the same
the processes run in isolated environments altogether (e.g. dockerized)
the file has been deleted/recreated in the meantime (meaning the inode doesn't match, even though the filename does)
Here's a simplified program that can serve as both parties:
Live On Coliru
#include <fstream>
#include <iostream>
#include <thread>
#include <boost/static_assert.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
namespace bip = boost::interprocess;
using namespace std::chrono_literals;
static inline auto constexpr lock_path = "lockfile";
int main() {
bip::file_lock lock(lock_path);
if (lock.try_lock()) {
std::ofstream stream(lock_path, std::ios::app);
std::cout << "got lock" << std::endl;
std::this_thread::sleep_for(2s);
}
std::cout << "bye" << std::endl;
}
Local demo:
#include "Stdafx.h"
#include "FishTracker.h"
#include <string>
#include "Utils.h"
#include <fstream>
using namespace std;
using namespace cv;
int main()
{
std::string videopath;
videopath = "E:\\TUKLNUST\\fishdata2\\Damo\\AR2-6\\Tetraodontidae_Lagocephalus_sceleratus_AD\\00001\\";
ifstream str;
str.open((videopath + DATA_TXT).c_str());
if (str.is_open())
{
cout << "file is open.";
}
}
file is open but str is this.
+ str {_Filebuffer={_Set_eback=0xcccccccc <Error reading characters of string.> _Set_egptr=0xcccccccc <Error reading characters of string.> ...} } std::basic_ifstream<char,std::char_traits<char> >
Configs:
win32, Debug
Visual Studio 2013
#include "Stdafx.h"
#include "FishTracker.h"
#include <string>
#include "Utils.h"
#include <fstream>
using namespace std;
using namespace cv;
int main()
{
std::string videopath;
videopath = "E:\\TUKLNUST\\fishdata2\\Damo\\AR2-6\\Tetraodontidae_Lagocephalus_sceleratus_AD\\00001\\";
ifstream str;
str.open((videopath + "DATA_TXT").c_str());
if (str.is_open())
{
cout << "file is open.";
}
}
boost::iostream bzip2_decompressor not decompressing file compressed by bzip2_compressor
Here's a simple self-contained example showing it to work:
Live On Coliru
#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <sstream>
namespace io = boost::iostreams;
int main()
{
std::stringstream ss;
{
io::filtering_stream<io::output> of;
of.push(io::bzip2_compressor{});
of.push(ss);
io::copy(std::cin, of);
}
std::cout << "Compressed input: " << ss.str().size() << " bytes\n";
ss.seekg(0ul);
{
io::filtering_stream<io::input> if_;
if_.push(io::bzip2_decompressor{});
if_.push(ss);
io::copy(if_, std::cout);
}
}
On Coliru it shows it compresses itself to 331 bytes, and back again to stdout
Perhaps you are forgetting to flush, have non-binary, whitespace skipping. We can't tell without a SSCCE
i'm trying to send json messages trough boost message_queue using ptree for storing informations localy.
this is the code of the receiver:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <iostream>
#include <string>
//#include <boost/archive/text_iarchive.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/serialization/string.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree; using boost::property_tree::read_json;
#define MAX_SIZE 1000
int main()
{
message_queue mq (boost::interprocess::open_or_create,"coda",10,MAX_SIZE);
message_queue::size_type recv_size;
unsigned int priority;
ptree pt;
std::stringstream iss;
std::string serialized_string;
serialized_string.resize(MAX_SIZE);
mq.receive(&serialized_string[0],MAX_SIZE,recv_size,priority);
iss << serialized_string;
std::istringstream is(iss.str());
read_json(is, pt);
std::cout pt.get<std::string>("prefix") << pt.get<std::string>("faceID") << std::endl;
}
and this is the code of th sender:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/serialization/string.hpp>
#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree; using boost::property_tree::write_json;
#define MAX_SIZE 1000
void send(ptree pt)
{
std::stringstream oss;
write_json(oss,pt);
std::string serialized_strings(oss.str());
message_queue mq(boost::interprocess::open_only,"coda");
mq.send(serialized_strings.data(), serialized_strings.size(),0);
std::cout << oss.str() << std::endl;
}
int main()
{
ptree pt;
pt.put("prefix","standard");
pt.put("faceID",42);
send(pt);
}
the sender works and have this output:
$ ./sendptree
{
"prefix": "standard",
"faceID": "42"
}
the receiver receive the data correctly but fail to parse it (with the read_json call).
$ ./recvptree
{
"prefix": "standard",
"faceID": "42"
}
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::property_tree::json_parser::json_parser_error> >'
what(): <unspecified file>(5): expected end of input
[1] 24052 abort ./recvptree
I think it was just that your receive buffer was not null terminated. This code works:
Server:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/serialization/string.hpp>
#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree; using boost::property_tree::write_json;
#define MAX_SIZE 1000
void send(ptree pt)
{
std::stringstream oss;
write_json(oss,pt);
message_queue mq(boost::interprocess::open_or_create,"coda",10,MAX_SIZE);
mq.send(oss.str().c_str(), oss.str().size(),0);
std::cout << oss.str() << std::endl;
system("PAUSE");
}
int main()
{
ptree pt;
pt.put("prefix","standard");
pt.put("faceID",42);
send(pt);
}
Client:
#include <boost/interprocess/ipc/message_queue.hpp>
#include <string>
#include <strstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/serialization/string.hpp>
using boost::interprocess::message_queue;
using boost::property_tree::ptree;
using boost::property_tree::read_json;
#define MAX_SIZE 1000
int main()
{
message_queue mq (boost::interprocess::open_or_create,"coda",10,MAX_SIZE);
size_t recv_size;
unsigned int priority;
ptree pt;
char buffer[MAX_SIZE];
mq.receive(buffer,MAX_SIZE,recv_size,priority);
buffer[recv_size] = 0;
std::istringstream is(buffer);
read_json(is, pt);
std::cout << "prefix: " << pt.get<std::string>("prefix") << " -- faceID: " << pt.get<std::string>("faceID") << std::endl;
system("PAUSE");
}