Streams API For Fast-RTPS - c++

I want to use fast-rtps to publish video(streams data) to subscriber. While I publish ten consecutive jpg file successfully, every picture received by subscriber wastes a lot of time to processing because I use function get_byte_value get a pixel one by one.
Do anyone know how to publish and subscribe more efficiently by fast-rtps midleware? (Create a new type? other?)
Below is my publisher's and subscriber's code:
Publisher.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file PicturePublisher.cpp
*
*/
#include "Publisher.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <thread>
#include <time.h>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PicturePublisher::PicturePublisher()
: mp_participant(nullptr)
, mp_publisher(nullptr)
, m_DynType(DynamicType_ptr(nullptr))
{
}
bool PicturePublisher::init()
{
cv::Mat image = cv::imread("drone.jpg", 1);
std::vector<unsigned char> buffer;
cv::imencode(".jpg", image, buffer);
// Create basic builders
DynamicTypeBuilder_ptr struct_type_builder(DynamicTypeBuilderFactory::get_instance()->create_struct_builder());
DynamicType_ptr octet_type(DynamicTypeBuilderFactory::get_instance()->create_byte_type());
DynamicTypeBuilder_ptr sequence_type_builder(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_type, 3873715));
DynamicType_ptr sequence_type = sequence_type_builder->build();
// Add members to the struct. By the way, id must be consecutive starting by zero.
struct_type_builder->add_member(0, "index", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(1, "size", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(2, "Picture", sequence_type);
struct_type_builder->set_name("Picture"); // Need to be same with topic data type
DynamicType_ptr dynType = struct_type_builder->build();
m_DynType.SetDynamicType(dynType);
m_DynHello = DynamicDataFactory::get_instance()->create_data(dynType);
m_DynHello->set_uint32_value(0, 0);
m_DynHello->set_uint32_value(buffer.size(), 1);
MemberId id;
// std::cout << "init: " << id << std::endl;
DynamicData* sequence_data = m_DynHello->loan_value(2);
for (int i = 0; i < buffer.size(); i++) {
if (i == buffer.size() - 1) {
std::cout << "Total Size: " << i + 1 << std::endl;
}
sequence_data->insert_byte_value(buffer[i], id);
}
m_DynHello->return_loaned_value(sequence_data);
ParticipantAttributes PParam;
PParam.rtps.setName("DynPicture_pub");
mp_participant = Domain::createParticipant(PParam, (ParticipantListener*)&m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE PUBLISHER
PublisherAttributes Wparam;
Wparam.topic.topicKind = NO_KEY;
Wparam.topic.topicDataType = "Picture";
Wparam.topic.topicName = "PictureTopic";
mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener);
if (mp_publisher == nullptr)
{
return false;
}
return true;
}
PicturePublisher::~PicturePublisher()
{
Domain::removeParticipant(mp_participant);
DynamicDataFactory::get_instance()->delete_data(m_DynHello);
Domain::stopAll();
}
void PicturePublisher::PubListener::onPublicationMatched(
Publisher* /*pub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
firstConnected = true;
std::cout << "Publisher matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Publisher unmatched" << std::endl;
}
}
void PicturePublisher::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PicturePublisher::runThread(
uint32_t samples,
uint32_t sleep)
{
uint32_t i = 0;
while (!stop && (i < samples || samples == 0))
{
if (publish(samples != 0))
{
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
std::cout << "runThreading...; \tSample Index: " << index << "; \t";
uint32_t size;
m_DynHello->get_uint32_value(size, 1);
std::cout << "size: " << size << std::endl;
if (i == 9){
std::cout << "Structure message" << " with index: " << i + 1 << " SENT" << std::endl;
// Avoid unmatched condition impact subscriber receiving message
std::cout << "Wait within twenty second..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
}
++i;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
}
}
void PicturePublisher::run(
uint32_t samples,
uint32_t sleep)
{
stop = false;
std::thread thread(&PicturePublisher::runThread, this, samples, sleep);
if (samples == 0)
{
std::cout << "Publisher running. Please press enter to stop the Publisher at any time." << std::endl;
std::cin.ignore();
stop = true;
}
else
{
std::cout << "Publisher running " << samples << " samples." << std::endl;
}
thread.join();
}
bool PicturePublisher::publish(
bool waitForListener)
{
// std::cout << "m_listener.n_matched: " << m_listener.n_matched << std::endl;
if (m_listener.firstConnected || !waitForListener || m_listener.n_matched > 0)
{
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
m_DynHello->set_uint32_value(index + 1, 0);
mp_publisher->write((void*)m_DynHello);
return true;
}
return false;
}
In PicturePublisher::init() function
Subsciber.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file Subscriber.cpp
*
*/
#include "Subscriber.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/SubscriberAttributes.h>
#include <fastrtps/subscriber/Subscriber.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PictureSubscriber::PictureSubscriber()
: mp_participant(nullptr)
, mp_subscriber(nullptr)
, m_DynType(DynamicType_ptr(nullptr))
{
}
struct timespec begin, end;
double elapsed;
std::vector<unsigned char> buffer;
bool PictureSubscriber::init()
{
ParticipantAttributes PParam;
PParam.rtps.setName("DynPicture_sub");
mp_participant = Domain::createParticipant(PParam, (ParticipantListener*)&m_part_list);
if (mp_participant == nullptr)
{
return false;
}
// Create basic builders
DynamicTypeBuilder_ptr struct_type_builder(DynamicTypeBuilderFactory::get_instance()->create_struct_builder());
DynamicTypeBuilder_ptr octet_builder(DynamicTypeBuilderFactory::get_instance()->create_byte_builder());
DynamicTypeBuilder_ptr sequence_type_builder(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_builder.get(), 3873715));
DynamicType_ptr sequence_type = sequence_type_builder->build();
// Add members to the struct.
struct_type_builder->add_member(0, "index", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(1, "size", DynamicTypeBuilderFactory::get_instance()->create_uint32_type());
struct_type_builder->add_member(2, "Picture", sequence_type);
struct_type_builder->set_name("Picture");
DynamicType_ptr dynType = struct_type_builder->build();
m_DynType.SetDynamicType(dynType);
m_listener.m_DynHello = DynamicDataFactory::get_instance()->create_data(dynType);
//REGISTER THE TYPE
Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE SUBSCRIBER
SubscriberAttributes Rparam;
Rparam.topic.topicKind = NO_KEY;
Rparam.topic.topicDataType = "Picture";
Rparam.topic.topicName = "PictureTopic";
mp_subscriber = Domain::createSubscriber(mp_participant, Rparam, (SubscriberListener*)&m_listener);
if (mp_subscriber == nullptr)
{
return false;
}
return true;
}
PictureSubscriber::~PictureSubscriber()
{
Domain::removeParticipant(mp_participant);
DynamicDataFactory::get_instance()->delete_data(m_listener.m_DynHello);
Domain::stopAll();
}
void PictureSubscriber::SubListener::onSubscriptionMatched(
Subscriber* /*sub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
std::cout << "Subscriber matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Subscriber unmatched" << std::endl;
}
}
void PictureSubscriber::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PictureSubscriber::SubListener::onNewDataMessage(
Subscriber* sub)
{
if (sub->takeNextData((void*)m_DynHello, &m_info))
{
if (m_info.sampleKind == ALIVE)
{
this->n_samples++;
// Print your structure data here.
uint32_t index;
m_DynHello->get_uint32_value(index, 0);
std::cout << "index: " << index << "; \t";
uint32_t size;
m_DynHello->get_uint32_value(size, 1);
std::cout << "size: " << size << std::endl;
DynamicType_ptr octet_type_temp(DynamicTypeBuilderFactory::get_instance()->create_byte_type());
DynamicTypeBuilder_ptr sequence_type_builder_temp(DynamicTypeBuilderFactory::get_instance()->create_sequence_builder(octet_type_temp, 3873715));
DynamicType_ptr sequence_type_temp = sequence_type_builder_temp->build();
DynamicData* sequence_data_temp = m_DynHello->loan_value(2);
for (int i = 0; i < size; i++) {
buffer.push_back(sequence_data_temp->get_byte_value(i));
}
m_DynHello->return_loaned_value(sequence_data_temp);
cv::Mat imageDecoded = cv::imdecode(buffer, 1);
cv::imwrite(std::to_string(index) + "_droneNew.jpg", imageDecoded);
}
}
}
void PictureSubscriber::run()
{
std::cout << "Subscriber running. Please press enter to stop the Subscriber" << std::endl;
std::cin.ignore();
}
void PictureSubscriber::run(
uint32_t number)
{
std::cout << "Subscriber running until " << number << "samples have been received" << std::endl;
while (number > this->m_listener.n_samples)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
In PictureSubscriber::SubListener::onNewDataMessage(Subscriber* sub) function

Here at eProsima, we have found some solutions to the problem you point out.
Firstly, please note that you don't need to use Dynamic Types to define the type that contains the image you are going to transmit. The easiest thing to do in your case is to define your type through an IDL file. Using the IDL file and the Fast-DDS-Gen tool you can generate the code for access to the data type elements, as well as automatically generate the data serialization and deserialization functions. In the Picture.idl file you will find the type defined in IDL format that best suits the data type you have created with dynamic types. Here you can find a guide on how to use the Fast-DDS-Gen tool. In this documentation you will also find a complete example of how an IDL file can be used to generate a complete DDS publisher/subscriber application, as well as the supported formats for the data. Also below are the files Publisher.cpp and Subscriber.cpp which have been modified according to the new data type.
We also recommend you to take a look at the example HelloWorldExample, as it is the one that best suits your needs. In this example you can also discover the new DDS API, included in the latest version of Fast DDS (2.1.0).
As an additional comment, we recommend that, instead of transmitting an octet vector, you encode the image in string base64 format before transmitting it since it's one of the most widespread formats for image transmission.
Picture.idl
struct Picture
{
unsigned long index;
unsigned long size;
sequence<octet> picture;
};
Publisher.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file PicturePublisher.cpp
*
*/
#include "PicturePublisher.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <thread>
#include <time.h>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PicturePublisher::PicturePublisher()
: mp_participant(nullptr)
, mp_publisher(nullptr)
{
}
bool PicturePublisher::init()
{
cv::Mat image = cv::imread("dog.jpg", cv::IMREAD_COLOR);
if(image.empty())
{
std::cout << "Could not read the image." << std::endl;
return false;
}
cv::imshow("Display window", image);
int k = cv::waitKey(0);
std::vector<unsigned char> buffer;
if(!cv::imencode(".jpg", image, buffer)){
printf("Image encoding failed");
}
m_Picture.index(0);
m_Picture.size(buffer.size());
m_Picture.picture(buffer);
ParticipantAttributes PParam;
PParam.rtps.setName("Picture_pub");
mp_participant = Domain::createParticipant(PParam, &m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerType(mp_participant, &m_type);
// Domain::registerDynamicType(mp_participant, &m_DynType);
//CREATE THE PUBLISHER
PublisherAttributes Wparam;
Wparam.topic.topicKind = NO_KEY;
Wparam.topic.topicDataType = "Picture";
Wparam.topic.topicName = "PictureTopic";
mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener);
if (mp_publisher == nullptr)
{
return false;
}
return true;
}
PicturePublisher::~PicturePublisher()
{
Domain::removeParticipant(mp_participant);
}
void PicturePublisher::PubListener::onPublicationMatched(
Publisher* /*pub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
firstConnected = true;
std::cout << "Publisher matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Publisher unmatched" << std::endl;
}
}
void PicturePublisher::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PicturePublisher::runThread(
uint32_t samples,
uint32_t sleep)
{
uint32_t i = 0;
while (!stop && (i < samples || samples == 0))
{
if (publish(samples != 0))
{
std::cout << "runThreading...; \tSample Index: " << m_Picture.index() << "; \t";
std::cout << "size: " << m_Picture.size() << std::endl;
if (i == 9){
std::cout << "Structure message" << " with index: " << i + 1 << " SENT" << std::endl;
// Avoid unmatched condition impact subscriber receiving message
std::cout << "Wait within twenty second..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
}
++i;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep));
}
}
void PicturePublisher::run(
uint32_t samples,
uint32_t sleep)
{
stop = false;
std::thread thread(&PicturePublisher::runThread, this, samples, sleep);
if (samples == 0)
{
std::cout << "Publisher running. Please press enter to stop the Publisher at any time." << std::endl;
std::cin.ignore();
stop = true;
}
else
{
std::cout << "Publisher running " << samples << " samples." << std::endl;
}
thread.join();
}
bool PicturePublisher::publish(
bool waitForListener)
{
// std::cout << "m_listener.n_matched: " << m_listener.n_matched << std::endl;
if (m_listener.firstConnected || !waitForListener || m_listener.n_matched > 0)
{
m_Picture.index(m_Picture.index() + 1);
mp_publisher->write((void*)&m_Picture);
return true;
}
return false;
}
Subscriber.cpp
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// Hpshboss modifys code from eprosima's github example;
// Licensed under the Apache License, Version 2.0 (the "License");
/**
* #file Subscriber.cpp
*
*/
#include "PictureSubscriber.h"
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/SubscriberAttributes.h>
#include <fastrtps/subscriber/Subscriber.h>
#include <fastrtps/Domain.h>
#include <fastrtps/types/DynamicTypeBuilderFactory.h>
#include <fastrtps/types/DynamicDataFactory.h>
#include <fastrtps/types/DynamicTypeBuilder.h>
#include <fastrtps/types/DynamicTypeBuilderPtr.h>
#include <fastrtps/types/DynamicType.h>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
#include <opencv2/opencv.hpp>
using namespace eprosima::fastrtps;
using namespace eprosima::fastrtps::rtps;
using namespace eprosima::fastrtps::types;
// using namespace cv;
PictureSubscriber::PictureSubscriber()
: mp_participant(nullptr)
, mp_subscriber(nullptr)
{
}
struct timespec begin, end;
double elapsed;
std::vector<unsigned char> buffer;
bool PictureSubscriber::init()
{
ParticipantAttributes PParam;
PParam.rtps.setName("Picture_sub");
mp_participant = Domain::createParticipant(PParam, &m_part_list);
if (mp_participant == nullptr)
{
return false;
}
//REGISTER THE TYPE
Domain::registerType(mp_participant, &m_type);
//CREATE THE SUBSCRIBER
SubscriberAttributes Rparam;
Rparam.topic.topicKind = NO_KEY;
Rparam.topic.topicDataType = "Picture";
Rparam.topic.topicName = "PictureTopic";
mp_subscriber = Domain::createSubscriber(mp_participant, Rparam, (SubscriberListener*)&m_listener);
if (mp_subscriber == nullptr)
{
return false;
}
return true;
}
PictureSubscriber::~PictureSubscriber()
{
Domain::removeParticipant(mp_participant);
}
void PictureSubscriber::SubListener::onSubscriptionMatched(
Subscriber* /*sub*/,
MatchingInfo& info)
{
if (info.status == MATCHED_MATCHING)
{
n_matched++;
std::cout << "Subscriber matched" << std::endl;
}
else
{
n_matched--;
std::cout << "Subscriber unmatched" << std::endl;
}
}
void PictureSubscriber::PartListener::onParticipantDiscovery(
Participant*,
ParticipantDiscoveryInfo&& info)
{
if (info.status == ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " discovered" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::REMOVED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " removed" << std::endl;
}
else if (info.status == ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
std::cout << "Participant " << info.info.m_participantName << " dropped" << std::endl;
}
}
void PictureSubscriber::SubListener::onNewDataMessage(
Subscriber* sub)
{
std::cout << "Data received." << std::endl;
if (sub->takeNextData((void*)&m_Picture, &m_info))
{
if (m_info.sampleKind == ALIVE)
{
this->n_samples++;
// Print your structure data here.
uint32_t index = m_Picture.index();
std::cout << "index: " << index << "; \t";
std::cout << "size: " << m_Picture.size() << std::endl;
cv::Mat imageDecoded = cv::imdecode(m_Picture.picture(), 1);
cv::imwrite(std::to_string(index) + "_dog_received.jpg", imageDecoded);
}
}
}
void PictureSubscriber::run()
{
std::cout << "Subscriber running. Please press enter to stop the Subscriber" << std::endl;
std::cin.ignore();
}
void PictureSubscriber::run(
uint32_t number)
{
std::cout << "Subscriber running until " << number << "samples have been received" << std::endl;
while (number > this->m_listener.n_samples)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}

Related

c++ netplan ubuntu yaml read and create

i have create a c++ app and need to read Ubuntu Netplan yaml files.
I found many websites with a lot of helpful information. mostly everything just does not work with netplan files. it crashes every time, usually when I set the root node to network. However, it is necessary because you still do not know what network card it is.
network.yaml
network:
ethernets:
eth0:
addresses:
- 192.168.0.30/24
dhcp4: false
gateway4: "192.168.0.1"
nameservers:
addresses:
- "211.211.190.30"
- "211.160.60.1"
- "8.8.8.8"
search:
- Network.local
renderer: networkd
version: 2
it must save into a struct for another works.
Parsing yaml with yaml cpp
yaml-cpp Easiest way to iterate through a map with undefined values
yaml-cpp read sequence in item
http://albertocorona.com/yaml-cpp-a-small-tutorial-to-serialization/
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <dirent.h>
#include <yaml-cpp/yaml.h>
#include <yaml-cpp/node/node.h>
#include <yaml-cpp/node/iterator.h>
using namespace std;
static string path02 = "/Netzwerk.yaml";
struct NetInfo {
int ID;
string version;
string renderer;
string IF_Type;
string name;
string dhcp4;
vector<string> addresseIF;
string gateway4;
vector<string> NSsearch;
vector<string> NSaddress;
};
int main(){
NetInfo yamlsafe;
YAML::Node config = YAML::LoadFile(path02);
string NetzwerkTyp = config["network"]["ethernets"].as<std::string>();
string NetzManager = config["network"]["renderer"].as<string>();
string If_Name = config["network"]["eth0"].as<string>();
string DHCP4 = config["eth0"]["addresses"].as<string>();
string IP = config["eth0"]["dhcp4"].as<string>();
string Gateway = config["eth0"]["gateway4"].as<string>();
string NS_IP = config["nameservers"]["addresses"].as<string>();
string NS_Search = config["nameservers"]["search"].as<string>();
cout <<"NetzwerkTyp:" << "\t" << NetzwerkTyp << endl;
cout <<"Netz Manager:" << "\t" << NetzManager << endl;
cout <<"If-Name:" << "\t" << If_Name << endl;
cout <<"DHCP4" << "\t" << DHCP4 << endl;
cout <<"IP" << "\t" << IP << endl;
cout <<"Gateway" << "\t" << Gateway << endl;
cout <<"NS-IP" << "\t" << NS_IP << endl;
cout <<"NS-Search" << "\t" << NS_Search << endl;
//second test
YAML::Node config1 = YAML::LoadFile(path02);
const YAML::Node& sensors = config1["network"];
for (YAML::const_iterator it = sensors.begin(); it != sensors.end(); ++it) {
const YAML::Node& sensor = *it;
std::cout << "address: " << sensor["addresses"].as<std::string>() << "\n";
std::cout << "dhcp: " << sensor["dhcp4"].as<std::string>() << "\n";
}
return 0;
}
yes i had the same think i've bin see this tipe but
nothing is what it makes. it hange up the QT ide.
my second thing is the second test below.
YAML::Node config1 = YAML::LoadFile(path02);
const YAML::Node& node1 = config1["network"];
//network: ------------------------>node2
const YAML::Node& node2 = node1["network"]["ethernets"];
// ethernets: ------------------>node3
const YAML::Node& node3 = node2["ethernets"]["eth0"];
// eth0: --------------------->node4
const YAML::Node& node4 = node3["eth0"]["addresses"];
// addresses: ----------------------N1-> - seq1
const vector& node4s1 = node4["addresses"];
// - 192.168.0.30/24-----------------> - seq1 -p1
const YAML::Node& node4 = node3["eth0"]["dhcp4"];
// dhcp4: false ------------------>node4-2
const YAML::Node& node4 = node3["eth0"]["gateway4"];
// gateway4: "192.168.0.1"-------->node4-3
const YAML::Node& node4 = node3["eth0"]["nameservers"];
// nameservers: ------------------>node4-4
const vector& node4s2 = node4["nameservers"]["addresses"];
// addresses: --------------------N5-> - seq2
// - "211.211.190.30"--------------> - seq2 - p1
// - "211.160.60.1"----------------> - seq2 - p2
// - "8.8.8.8"---------------------> - seq2 - p3
const vector& node4s3 = node4["nameservers"]["search"];
// search: -----------------------N6-> - seq3
// - Network.local-----------------> - seq3 - p1
const YAML::Node& node2 = node1["network"]["renderer"];
// renderer: networkd---------->node5
const YAML::Node& node2 = node1["network"]["version"];
// version: 2------------------>node6
this is what i thing about it but it is not working.
Ok this is the answer i have a struct and i can read all nodes.
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <dirent.h>
#include <yaml-cpp/yaml.h>
#include <yaml-cpp/node/iterator.h>
using namespace std;
struct DateiLesen {
string version;
string renderer;
string IF_Type;
string name;
string dhcp4;
string dhcp6;
vector<string> addresseIF;
string gateway4;
string gateway6;
vector<string> NSsearch;
vector<string> NSaddress;
};
static vector<DateiLesen> DLS2;
static string path = "/QTProjects/YAML-15/test/Netzwerk.yaml";
void Yaml_lesen(){
YAML::Node nodew = YAML::LoadFile(path);
string NetIf = "eth0";
DLS2.push_back(DateiLesen());
if (nodew["network"]) {
if (nodew["network"]["version"]) {
DLS2[0].version = nodew["network"]["version"].as<string>();
//std::cout << nodew["network"]["version"].as<std::string>() << "\n";
}
if (nodew["network"]["renderer"]) {
DLS2[0].renderer = nodew["network"]["renderer"].as<std::string>();
//std::cout << nodew["network"]["renderer"].as<std::string>() << "\n";
}
if (nodew["network"]["ethernets"]) {
DLS2[0].IF_Type = "ethernets";
if (nodew["network"]["ethernets"][NetIf]) {
if (nodew["network"]["ethernets"][NetIf]["dhcp4"]) {
DLS2[0].dhcp4 = nodew["network"]["ethernets"][NetIf]["dhcp4"].as<string>();
//std::cout << nodew["network"]["ethernets"][NetIf]["dhcp4"].as<std::string>() << "\n";
}
if (nodew["network"]["ethernets"][NetIf]["dhcp6"]) {
DLS2[0].dhcp6 = nodew["network"]["ethernets"][NetIf]["dhcp6"].as<string>();
//std::cout << nodew["network"]["ethernets"][NetIf]["dhcp6"].as<std::string>() << "\n";
}
if (nodew["network"]["ethernets"][NetIf]["addresses"]) {
if (nodew["network"]["ethernets"][NetIf]["addresses"].IsSequence()) {
for (unsigned long it = 0; it < nodew["network"]["ethernets"][NetIf]["addresses"].size(); ++it) {
DLS2[0].addresseIF.push_back(nodew["network"]["ethernets"][NetIf]["addresses"][it].as<std::string>());
//cout << nodew["network"]["ethernets"][NetIf]["addresses"][it].as<std::string>() << "\n";
}
}
}
if (nodew["network"]["ethernets"][NetIf]["gateway4"]) {
DLS2[0].gateway4 = nodew["network"]["ethernets"][NetIf]["gateway4"].as<string>();
//std::cout << nodew["network"]["ethernets"][NetIf]["gateway4"].as<std::string>() << "\n";
}
if (nodew["network"]["ethernets"][NetIf]["gateway6"]) {
DLS2[0].gateway6 = nodew["network"]["ethernets"][NetIf]["gateway6"].as<string>();
//std::cout << nodew["network"]["ethernets"][NetIf]["gateway4"].as<std::string>() << "\n";
}
if (nodew["network"]["ethernets"][NetIf]["nameservers"]) {
//cout << "Nameservers" << endl;
if (nodew["network"]["ethernets"][NetIf]["nameservers"]["search"]) {
if (nodew["network"]["ethernets"][NetIf]["nameservers"]["search"].IsSequence()) {
for (unsigned long it = 0; it < nodew["network"]["ethernets"][NetIf]["nameservers"]["search"].size(); ++it) {
DLS2[0].NSsearch.push_back(nodew["network"]["ethernets"][NetIf]["nameservers"]["search"][it].as<std::string>());
//cout << nodew["network"]["ethernets"][NetIf]["nameservers"]["search"][it].as<std::string>() << "\n";
}
}
}
if (nodew["network"]["ethernets"][NetIf]["nameservers"]["addresses"]) {
if (nodew["network"]["ethernets"][NetIf]["nameservers"]["addresses"].IsSequence()) {
for (unsigned long it = 0; it < nodew["network"]["ethernets"][NetIf]["nameservers"]["addresses"].size(); ++it) {
DLS2[0].NSaddress.push_back(nodew["network"]["ethernets"][NetIf]["nameservers"]["addresses"][it].as<std::string>());
//cout << nodew["network"]["ethernets"][NetIf]["nameservers"]["addresses"][it].as<std::string>() << "\n";
}
}
}
}
}
}else if(nodew["network"]["wifis"]){
DLS2[0].IF_Type = "wifis";
if (nodew["network"]["wifis"][NetIf]) {
if (nodew["network"]["wifis"][NetIf]["dhcp4"]) {
DLS2[0].dhcp4 = nodew["network"]["wifis"][NetIf]["dhcp4"].as<string>();
//std::cout << nodew["network"]["wifis"][NetIf]["dhcp4"].as<std::string>() << "\n";
}
if (nodew["network"]["wifis"][NetIf]["dhcp6"]) {
DLS2[0].dhcp6 = nodew["network"]["wifis"][NetIf]["dhcp6"].as<string>();
//std::cout << nodew["network"]["wifis"][NetIf]["dhcp6"].as<std::string>() << "\n";
}
if (nodew["network"]["wifis"][NetIf]["addresses"]) {
if (nodew["network"]["wifis"][NetIf]["addresses"].IsSequence()) {
for (unsigned long it = 0; it < nodew["network"]["wifis"][NetIf]["addresses"].size(); ++it) {
DLS2[0].addresseIF.push_back(nodew["network"]["wifis"][NetIf]["addresses"][it].as<std::string>());
//cout << nodew["network"]["wifis"][NetIf]["addresses"][it].as<std::string>() << "\n";
}
}
}
if (nodew["network"]["wifis"][NetIf]["gateway4"]) {
DLS2[0].gateway4 = nodew["network"]["wifis"][NetIf]["gateway4"].as<string>();
//std::cout << nodew["network"]["wifis"][NetIf]["gateway4"].as<std::string>() << "\n";
}
if (nodew["network"]["wifis"][NetIf]["gateway6"]) {
DLS2[0].gateway6 = nodew["network"]["wifis"][NetIf]["gateway6"].as<string>();
//std::cout << nodew["network"]["wifis"][NetIf]["gateway4"].as<std::string>() << "\n";
}
if (nodew["network"]["wifis"][NetIf]["nameservers"]) {
cout << "Nameservers" << endl;
if (nodew["network"]["wifis"][NetIf]["nameservers"]["search"]) {
if (nodew["network"]["wifis"][NetIf]["nameservers"]["search"].IsSequence()) {
for (unsigned long it = 0; it < nodew["network"]["wifis"][NetIf]["nameservers"]["search"].size(); ++it) {
DLS2[0].NSsearch.push_back(nodew["network"]["wifis"][NetIf]["nameservers"]["search"][it].as<std::string>());
//cout << nodew["network"]["wifis"][NetIf]["nameservers"]["search"][it].as<std::string>() << "\n";
}
}
}
if (nodew["network"]["wifis"][NetIf]["nameservers"]["addresses"]) {
if (nodew["network"]["wifis"][NetIf]["nameservers"]["addresses"].IsSequence()) {
for (unsigned long it = 0; it < nodew["network"]["wifis"][NetIf]["nameservers"]["addresses"].size(); ++it) {
DLS2[0].NSaddress.push_back(nodew["network"]["wifis"][NetIf]["nameservers"]["addresses"][it].as<std::string>());
//cout << nodew["network"]["wifis"][NetIf]["nameservers"]["addresses"][it].as<std::string>() << "\n";
}
}
}
}
}
}else if(nodew["network"]["bonds"]){
}else if(nodew["network"]["bridges"]){
}else if(nodew["network"]["vlans"]){
}
}
}
int main(){
Yaml_lesen();
for (unsigned long S = 0; S < DLS2.size(); S++){
cout << DLS2[S].renderer << endl;
cout << DLS2[S].name << endl;
cout << DLS2[S].IF_Type << endl;
cout << DLS2[S].dhcp4 << endl;
for (unsigned long S2 = 0; S2 < DLS2[S].addresseIF.size(); S2++){
cout << DLS2[S].addresseIF[S2] << endl;
}
cout << DLS2[S].gateway4 << endl;
for (unsigned long S2 = 0; S2 < DLS2[S].addresseIF.size(); S2++){
cout << DLS2[S].NSsearch[S2] << endl;
}
for (unsigned long S2 = 0; S2 < DLS2[S].addresseIF.size(); S2++){
cout << DLS2[S].NSaddress[S2] << endl;
}
}
return 0;
}

How to sort files by descending the file size

I need to output the 5 largest files from the directory. For this, I use a boost filesystem c++. In the process of writing the program, I encountered difficulties. I can output all files from the directory, file size, file creation date and file attributes. In the vector I put the names of the files, but I just can not figure out how to sort by size. I need to output the 5 largest files from the specified directory. I think that you must first sort by file size by descending. That is, from a larger value to a smaller one. And then the scans are not needed. Most likely it needs to be done in a loop. Help me please.
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;
void ShowAttributes(DWORD attributes);
void AttribFile(const char* str);
void Attrib();
int main(int argc, char* argv[])
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
if (argc < 2)
{
cout << "Using Name Directory" << endl;
return 1;
}
path Part(argv[1]);
try
{
if (exists(Part))
{
if (is_regular_file(Part))
{
cout << Part << " Size " << file_size(Part) << " bytes ";
time_t Time = last_write_time(Part);
cout << asctime(localtime(&Time)) << endl;
}
else if (is_directory(Part))
{
cout << "Directory " << Part << " include:" << endl;
vector<string> vecList;
for (auto j : directory_iterator(Part))
vecList.push_back(j.path().filename().string());
sort(vecList.begin(), vecList.end());
string filePath;
for (auto i : vecList)
{
cout << " " << i;
filePath = Part.parent_path().string() + "/" + i;
if (is_regular_file(filePath))
{
if (Is_Executable_File(filePath))
cout << "*";
cout << " Size " << file_size(filePath) << " bytes ";
time_t Time = last_write_time(Part);
cout << asctime(localtime(&Time)) << endl;
AttribFile(filePath.c_str());
}
cout << endl;
}
}
}
else
cout << Part << " Erroe!" << endl;
}
catch (const filesystem_error& ex)
{
cout << ex.what() << endl;
}
return 0;
}
void ShowAttributes(DWORD attributes)
{
if (attributes & FILE_ATTRIBUTE_ARCHIVE)
cout << " archive" << endl;
if (attributes & FILE_ATTRIBUTE_DIRECTORY)
cout << " directory" << endl;
if (attributes & FILE_ATTRIBUTE_HIDDEN)
cout << " hidden" << endl;
if (attributes & FILE_ATTRIBUTE_NORMAL)
cout << " normal" << endl;
if (attributes & FILE_ATTRIBUTE_READONLY)
cout << " read only" << endl;
if (attributes & FILE_ATTRIBUTE_SYSTEM)
cout << " system" << endl;
if (attributes & FILE_ATTRIBUTE_TEMPORARY)
cout << " temporary" << endl;
}
void AttribFile(const char* str)
{
DWORD attributes;
attributes = GetFileAttributesA(str);
ShowAttributes(attributes);
}
void Attrib()
{
char filename[MAX_PATH];
DWORD attributes;
cout << "Name of file: ";
cin >> filename;
attributes = GetFileAttributesA(filename);
ShowAttributes(attributes);
}
create a class or struct to hold the information you need on each file, e.g.
struct MyFile
{
std::string name;
size_t size;
}
create a vector of these and read all files from your folder
then sort the vector and give a custom comparison (e.g. in form of a lambda), see Sorting a vector of custom objects for details on that
Here's a program based on just the standard library that does what you seem to intend:
Live On Coliru
Update: Using C++11 and Boost Filesystem instead: Live On Coliru
#include <algorithm>
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
namespace fs = std::filesystem;
struct tm *last_modified(fs::path const &p) {
auto ftime = fs::last_write_time(p);
auto cftime = decltype(ftime)::clock::to_time_t(ftime);
return std::localtime(&cftime);
}
bool is_executable(fs::path const& p) {
return fs::perms::none != (fs::status(p).permissions() &
(fs::perms::owner_exec |
fs::perms::group_exec |
fs::perms::others_exec));
}
void report(fs::path const& file) {
if (is_executable(file))
std::cout << "*";
std::cout << file << "\tSize:" << fs::file_size(file);
std::cout << "\tModified:" << std::asctime(last_modified(file));
}
template <typename Accessor, typename Cmp = std::less<> >
static auto compare_by(Accessor&& f, Cmp cmp = {}) {
return [f=std::forward<Accessor>(f),cmp](auto const& a, auto const& b) {
return cmp(f(a), f(b));
};
}
int main(int argc, char *argv[]) {
if (argc < 2) {
std::cout << "Using: " << argv[0] << " [Name|Directory]" << std::endl;
return 1;
}
fs::path filespec(argv[1]);
try {
if (is_regular_file(filespec)) {
// print
report(filespec);
} else if (is_directory(filespec)) {
std::cout << "Directory " << filespec << " include:" << std::endl;
std::vector<fs::directory_entry> const entries { fs::directory_iterator{filespec}, {} };
// filter just files
std::vector<fs::path> files;
std::remove_copy_if(entries.begin(), entries.end(),
back_inserter(files),
[](auto& de) { return de.is_directory(); });
// get the top 5, or fewer
auto b = files.begin(),
top5 = b + std::min(5ul, files.size()),
e = files.end();
// ordered by size, descending
std::partial_sort(b, top5, e,
compare_by([](auto& p) { return fs::file_size(p); }, std::greater<>{}));
files.erase(top5, e);
// print
for (auto& f : files)
report(f);
} else {
std::cout << filespec << " Error!" << std::endl;
}
} catch (const fs::filesystem_error &ex) {
std::cout << ex.what() << std::endl;
}
}
Prints, e.g. for ./a.out /usr/lib:
Directory "/usr/lib/" include:
"/usr/lib/libruby-1.9.1-static.a" Size:3654748 Modified:Wed Nov 19 21:41:25 2014
"/usr/lib/libruby-1.9.1.so.1.9.1" Size:2087600 Modified:Wed Nov 19 21:41:20 2014
"/usr/lib/libruby-1.9.1.so" Size:2087600 Modified:Wed Nov 19 21:41:20 2014
"/usr/lib/libruby-1.9.1.so.1.9" Size:2087600 Modified:Wed Nov 19 21:41:20 2014
"/usr/lib/libc++.so.1" Size:1460461 Modified:Mon Sep 8 20:01:17 2014

Trouble with modifying object values in a c++ vector

I am trying to develop an inventory system for a game in c++. I have 2 header files one is named item and the other inventory these are sent into my main method. The way I have my code set up is when I send an Item object to my inventory the inventory checks to see if an object with the same ID exists. If it does then get the quantity Item value and increment it by one. The problem is the change to the Quantity value does not save to the main Inventory object. Any and all help would be very appreciated. Also sorry if my code is bad! I am not going to include all the code, and I am sure that all the proper #include functions are in!
The real issue seems to be somewhere in the actual new Quantity value not being added to the main Inventory object.
#include "stdafx.h"
#include <iostream>
#include "Windows.h"
#include "Item.h"
#include "Inventory.h"
#include <ctime>
#include <fstream>
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <string>
#include <cstdio>
#include <vector>
// Functions!
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void setColor(int color) // 0 Black, 1 Blue, 2 Green, 3 Light Blue, 4Red 5 Purple 6 Yellow 7 White
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, color);
}
void clearColor()
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 7);
}
void ShowConsoleCursor(bool showFlag)
{
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(out, &cursorInfo);
cursorInfo.bVisible = showFlag; // set the cursor visibility
SetConsoleCursorInfo(out, &cursorInfo);
}
//
// Menu SetUp!
void menuArea()
{
gotoxy(40, 4);
setColor(2);
std::cout << "--------Menu--------" << std::endl;
gotoxy(40, 12);
std::cout << "--------------------" << std::endl;
clearColor();
}
void gatherArea()
{
gotoxy(45, 6);
setColor(3);
std::cout << "-Gather" << std::endl;
clearColor();
}
void recoveryArea()
{
gotoxy(45, 8);
setColor(5);
std::cout << "-Recovery" << std::endl;
clearColor();
}
void inventoryArea()
{
gotoxy(45, 10);
setColor(4);
std::cout << "-Inventory" << std::endl;
clearColor();
}
//
// Menu Selector!
void gatherOption()
{
gotoxy(40, 6);
std::cout << "(G)" << std::endl;
}
void recoverOption()
{
gotoxy(40, 8);
std::cout << "(R)" << std::endl;
}
void inventoryOption()
{
gotoxy(40, 10);
std::cout << "(I)" << std::endl;
}
void gatherSelected()
{
setColor(5);
gotoxy(40, 6);
std::cout << "(G)" << std::endl;
clearColor();
}
void recoverSelected()
{
setColor(5);
gotoxy(40, 8);
std::cout << "(R)" << std::endl;
clearColor();
}
void inventorySelected()
{
setColor(5);
gotoxy(40, 10);
std::cout << "(I)" << std::endl;
clearColor();
}
//
// Menu Viewer!
void viewClear()
{
gotoxy(0, 4);
for (int i = 0; i < 40; i++)
{
std::cout << "\t\t\t\t\t" << std::endl;
}
}
void viewGather()
{
gotoxy(12, 4);
std::cout << "-----Gather-----\n" << std::endl;
std::cout << "\t 1) Gather Wood (5 sec)\n" << std::endl;
std::cout << "\t 2) Gather Berries (5 sec)\n" << std::endl;
}
void viewRecover()
{
gotoxy(12, 4);
std::cout << "-----Recover-----\n" << std::endl;
std::cout << "\t 1) Eat Berries (5 sec)\n" << std::endl;
std::cout << "\t 2) Sleep (10 sec)\n" << std::endl;
}
//
// Figuring out the inventory
void viewInventory(Inventory inventory)
{
std::string inv = inventory.display(inventory);
gotoxy(12, 4);
std::cout << inv << std::endl;
}
Inventory setInventory(Inventory inventory)
{
Item woodItem(1, "Wood;");
Item berriesItem(2, "Berries");
inventory.addItem(woodItem);
inventory.addItem(berriesItem);
return inventory;
}
//
//Timer Stuff!
void timerSetup()
{
setColor(6);
gotoxy(5, 2);
std::cout << "Client Up Time:" << std::endl;
clearColor();
}
void getUpTime()
{
gotoxy(22, 2);
int seconds = (int)std::clock() / 1000;
int minutes = (int)seconds / 60;
seconds = seconds % 60;
if (seconds < 10 && minutes < 10)
std::cout << "0" << minutes << ":0" << seconds << std::endl;
else if (seconds < 10)
std::cout << minutes << ":0" << seconds << std::endl;
else if (minutes<10)
std::cout << "0" << minutes << ":" << seconds << std::endl;
else
std::cout << minutes << ":" << seconds << std::endl;
}
//
void drawMenu()
{
menuArea();
gatherArea();
recoveryArea();
inventoryArea();
timerSetup();
gatherOption();
recoverOption();
inventoryOption();
}
int main()
{
Inventory inventory;
drawMenu();
std::clock_t start;
inventory = setInventory(inventory);
while (true)
{
ShowConsoleCursor(false);
getUpTime();
if (GetAsyncKeyState(0x47)) //G
{
gatherSelected();
recoverOption();
inventoryOption();
viewClear();
viewGather();
}
if (GetAsyncKeyState(0x52))//R
{
recoverSelected();
gatherOption();
inventoryOption();
viewClear();
viewRecover();
}
if (GetAsyncKeyState(0x49))//I
{
Item admin(0, "Test");
inventory.addItem(admin);
inventorySelected();
gatherOption();
recoverOption();
viewClear();
Item bannana(3, "Bannana");
inventory.addItem(bannana);
viewInventory(inventory);
}
if (GetAsyncKeyState(VK_ESCAPE))//Esc
{
inventoryOption();
gatherOption();
recoverOption();
viewClear();
}
}
}
Item.h File!
#include <string>
#pragma once
class Item
{
public:
int getId();
int getQuantity();
std::string getName();
void setQuantity(int set);
Item(int id, std::string name);
private :
int id;
std::string name;
int quantity;
};
Item::Item(int id, std::string name)
{
Item::id = id;
Item::name = name;
}
int Item::getQuantity()
{
return quantity;
}
int Item::getId()
{
return id;
}
std::string Item::getName()
{
return name;
}
void Item::setQuantity(int set)
{
quantity = set;
}
Inventory.h Header File!
#include "Item.h"
#include <vector>
#include <iostream>
#pragma once
class Inventory
{
public:
Inventory();
std::vector<Item> inventory;
void addItem(Item item);
std::string display(Inventory inventory);
};
Inventory::Inventory()
{
}
void Inventory::addItem(Item item)
{
int id = item.getId();
boolean added = false;
for (Item check : Inventory::inventory)
{
if (id == check.getId())
{
int x = check.getQuantity();
x++;
check.setQuantity(x);
std::cout << "Check!" << check.getQuantity() << check.getName();
added = true;
}
}
if (!added)
{
item.setQuantity(0);
Inventory::inventory.push_back(item);
}
}
std::string Inventory::display(Inventory inventory)
{
std::string display = "---Inventory---\n";
display += "\n--------------------------------------\n";
if (Inventory::inventory.size()== 0)
return display;
else
{
for (Item item : Inventory::inventory)
{
display += " Name: " + item.getName();
display += " Id: " + std::to_string(item.getId());
display += " Quantity: " + std::to_string(item.getQuantity());
display += "\n--------------------------------------\n";
}
return display;
}
}
Your issue is in this line:
for (Item check : Inventory::inventory)
You modify check, but check is a copy of items in your inventory! Loop through with check being a reference instead:
for (Item &check : Inventory::inventory)
^^^
Also, when you first get an item, you set its quantity to 0:
item.setQuantity(0);
Is this intentional? Perhaps you mean to set it to 1 instead:
item.setQuantity(1);
Or even better, add a set to 1 in the constructor! (after all, when an item is made it's because we have at least one of it, right?). And while your at it, you can switch to a field initialization list with your constructors to make life easier as well:
Item::Item(int id, std::string name) : id(id), name(name), quantity(1) { }

When calling delete for LinkedList, variable is being assigned different memory

I am using a linked list to store information on binary bits. Degree tells which power to raise an integer, 2, to.
The problem occurs in my set_bit method. It is supposed to delete the node pointer "currentSet" once the "target" node pointer is found. However instead of setting "currentSet" to null/releasing the memory, currentSet is being given a different, lower memory address. Why is this? What am I doing wrong? The program works when I explicitly sell currentSet to nullptr but shouldn't delete currentSet do this as well?
Here is the implementation of header
//file is "binary.cpp"
#include <iostream>
#include "binary.h"
//using std::cout;
Binary::Binary(int x) {
firstTerm = nullptr;
while (x > 0) {
unsigned int degree = (unsigned int) (log(float(x)) / log(float(2)));
set_bit(1, degree);
x -= (int) pow(float(2), float(degree));
}
}
Binary::~Binary() {
BinaryNode *temp;
while (firstTerm != nullptr) {
temp = firstTerm->next;
delete firstTerm;
firstTerm = temp;
}
}
void Binary::set_bit(int bit, int degree) {
BinaryNode *currentSet = firstTerm;
BinaryNode *target;
std::cout << "get_bit returns " << get_bit(degree) << std::endl;
if (bit == 0 && get_bit(degree)) {
std::cout << "bit = 0 " << std::endl;
std::cout << "currentSet->degree " << currentSet->degree << std::endl;
if (currentSet->degree == degree) {
std::cout << "in if" << std::endl;
firstTerm = currentSet->next;
delete currentSet;
std::cout << "end if" << std::endl;
}
else {
target = currentSet;
std::cout << "in else" << std::endl;
while (currentSet != nullptr) {
if (currentSet->degree == degree) {
std::cout << "in nested if" << std::endl;
//std::cout << "currentSet->degree = " << currentSet->degree << std::endl;
target->next = currentSet->next;
std::cout << "currentSet before delete " << currentSet << std::endl;
delete currentSet;
std::cout << "currentSet " << currentSet << "\nend nested if" << std::endl;
}
else {
std::cout << "in nested else" << std::endl;
std::cout << "firstTerm->next = " << firstTerm->next << std::endl;
std::cout << "currentSet->next = " << currentSet->next << std::endl;
target = currentSet;
currentSet = currentSet->next;
std::cout << "currentSet->next = " << currentSet->next << std::endl;
std::cout << "end nested else\n";
}
}
}
}
else if (bit == 1 && get_bit(degree) == 0) {
std::cout << "bit = 1" << std::endl;
firstTerm = new BinaryNode(degree, firstTerm);
/*if (firstTerm->next nullptr) {
currentSet = firstTerm;
}*/
std::cout << "firstTerm = " << firstTerm << std::endl;
std::cout << "firstTerm->degree = " << firstTerm->degree << std::endl;
std::cout << "firstTerm->next = " << firstTerm->next << std::endl;
}
}
int Binary::get_bit(int degree) const {
BinaryNode *currentGet = firstTerm;
while (currentGet != nullptr) {
//std::cout << "currentGet != nullptr";
if (currentGet->degree == degree) {
return 1;
}
currentGet = currentGet->next;
}
return 0;
}
Here is the header
//file is "binary.h"
#ifndef _BINARY_H_
#define _BINARY_H_
#include <iostream>
class Binary {
private:
struct BinaryNode {
int degree;
BinaryNode* next;
BinaryNode(int d, BinaryNode* n): degree(d),next(n) {}
};
BinaryNode *firstTerm;
public:
// default constructor
Binary() {
firstTerm = nullptr;
}
void set_bit(int b, int d);
int get_bit(int d) const;
#endif
Here is the tester file
//file is "binary_main.cpp
#include <iostream>
#include "binary.h"
using namespace std;
int main (void)
{
cout << "\nTESTING GET AND SET METHODS" << endl;
b1.set_bit(1, 2);
b1.set_bit(1, 5);
b1.set_bit(1, 0);
b1.set_bit(0, 2);
}
edited
Explicitly set currentSet to nullptr,
answer was found using information from n.m.

Simple timer mechanism with boost - Issue [Re-rum of run mechanism does not respond with handler message]

Am very much new to C++ and boost library
i have constructed a simple timer mechanism
my issue :
On the first timer run call timer.StartAppTimer(1,10); i am getting the handler message
but when i re-run the start timeer again it says started but after 10 seconds i don't receive no handler message..
Please guide
Below is my code:
#include <iostream>
#include <windows.h>
#include <timer.h>
#define sleep(n) Sleep(1000 * n)
using namespace boost::posix_time;
using namespace std;
void handler1(int id,const boost::system::error_code &ec)
{
if (ec == boost::asio::error::operation_aborted)
{
std::cout << microsec_clock::local_time() << " Handler1: Timer 1 was cancelled or retriggered." << std::endl;
std::cout << "TIMER ID : " << id<< std::endl;
}
else
{
std::cout << microsec_clock::local_time() << " Handler1: expired." << std::endl;
std::cout << "fsm RECIEVE msgBuf : " << id<< std::endl;
}
}
Mytimer::Mytimer()
: m_pTimer(NULL),
m_pThread(NULL)
{
m_pTimer = new boost::asio::deadline_timer(io_service1);
}
void Mytimer::runTimerThread()
{
std::cout << "IO Service started " << std::endl;
io_service1.run();
}
void Mytimer::startTimer(int time,int timerId)
{
m_pTimer->expires_from_now(boost::posix_time::seconds(time));
m_pTimer->async_wait(boost::bind(handler1,timerId,boost::asio::placeholders::error));
m_pThread = new boost::thread(&Mytimer::runTimerThread, this);
}
void Mytimer::stopTimer()
{
io_service1.reset();
io_service1.stop();
}
bool Mytimer::isRunning()
{
time_duration td = m_pTimer->expires_from_now();
if (td.total_seconds() > 0)
{
return true;
}
return false;
}
void TimerAccess::StartAppTimer(int Timerid,int TimerPeriod){
std::cout << "TIMER ID : " << Timerid<< std::endl;
if (Timerid == APPTIMER1){
timer1.startTimer(TimerPeriod,Timerid);
}
if (Timerid == APPTIMER2){
timer2.startTimer(TimerPeriod,Timerid);
}
if (Timerid == APPTIMER3){
timer3.startTimer(TimerPeriod,Timerid);
}
}
void TimerAccess::StopTimer(int Timerid){
if (Timerid == APPTIMER1){
timer1.stopTimer();
}
if (Timerid == APPTIMER2){
timer2.stopTimer();
}
if (Timerid == APPTIMER3){
timer3.stopTimer();
}
// return -1;
}
int main()
{
cout << " before timer construction" << endl;
TimerAccess timer;
timer.StartAppTimer(1,10);
sleep(15);
cout << " before starting timer 2" << endl;
timer.StartAppTimer(1,10);
sleep(30);
cout << " END OF MAIN " << endl;
}