Im having issues with my code. Its been a few years since I last wrote a even a basic program. My current issue is my program is supposed to count the number of characters entered by the user and return the count of a single char also entered by the user. Where am I going wrong at? I know it has to do with the space between words. Probably a noob mistake. Thanks in advance.
#include <iostream>
#include <string>
#include<stdio.h>
#include<ctype.h>
using namespace std;
int numTimesAppear(char *mystring, char ch)//numTimes Appear function
{
int i;
int count=0;
for (i = 0; i < 100; i++)
{
if (mystring[i] == ch)
count++;
}
return count;
}
int main()
{
char str[100];
char ch;
int nooftimes;
cout << ("Enter a string of characters:") << endl;
cin >> str;
cout << ("Enter a character to count:") << endl;
cin >> ch;
cout << numTimesAppear(str, ch);
return 0;
}
I'm trying to use boost library 1.55.0 to create a shared memory.I have a example.cpp file which creates boost shared memory. Mexing of this file is successful,but throws the following exception while debugging "MATLAB.exe has triggered a breakpoint".Is this exception because of the version of the boost being incompatible with the matlab version? How to resolve this
`/* File : sfun_counter_cpp.cpp
* Abstract:
*
* Example of an C++ S-function which stores an C++ object in
* the pointers vector PWork.
*
* Copyright 1990-2000 The MathWorks, Inc.
*
*/
#include "iostream"
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
typedef struct
{
int outGate;
unsigned int outPin;
int inGate;
unsigned int inPin;
} wire;
typedef struct
{
unsigned int gateType;
unsigned int inPins;
unsigned int outPins;
std::vector<wire> inWires;
std::vector<wire> outWires;
} gate;
std::vector<gate> gates;
wire wiredata;
gate gatedata;
class counter {
double x;
public:
counter() {
x = 0.0;
}
double output(void) {
x = x + 1.0;
return x;
}
};
#ifdef __cplusplus
extern "C" { // use the C fcn-call standard for all functions
#endif // defined within this scope
#define S_FUNCTION_LEVEL 2
#define S_FUNCTION_NAME sfun_counter_cpp
/*
* Need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
/*====================*
* S-function methods *
*====================*/
/* Function: mdlInitializeSizes ===============================================
* Abstract:
* The sizes information is used by Simulink to determine the S-function
* block's characteristics (number of inputs, outputs, states, etc.).
*/
static void mdlInitializeSizes(SimStruct *S)
{
/* See sfuntmpl_doc.c for more details on the macros below */
ssSetNumSFcnParams(S, 1); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Return if number of expected != number of actual parameters */
return;
}
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 0)) return;
if (!ssSetNumOutputPorts(S, 1)) return;
ssSetOutputPortWidth(S, 0, 1);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 1); // reserve element in the pointers vector
ssSetNumModes(S, 0); // to store a C++ object
ssSetNumNonsampledZCs(S, 0);
ssSetOptions(S, 0);
}
/* Function: mdlInitializeSampleTimes
=========================================
* Abstract:
* This function is used to specify the sample time(s) for your
* S-function. You must register the same number of sample times as
* specified in ssSetNumSampleTimes.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, mxGetScalar(ssGetSFcnParam(S, 0)));
ssSetOffsetTime(S, 0, 0.0);
}
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
/* Function: mdlStart
=======================================================
* Abstract:
* This function is called once at start of model execution. If you
* have states that should be initialized once, this is the place
* to do it.
*/
static void mdlStart(SimStruct *S)
{
ssGetPWork(S)[0] = (void *) new counter; // store new C++ object in
the
} // pointers vector
#endif /* MDL_START */
/* Function: mdlOutputs =======================================================
* Abstract:
* In this function, you compute the outputs of your S-function
* block. Generally outputs are placed in the output vector, ssGetY(S).
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
using namespace boost::interprocess;
counter *c = (counter *) ssGetPWork(S)[0]; // retrieve C++ object from
shared_memory_object::remove("MySharedMemory");
//create the shared memory
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
//create the allocators for the struct elements to be accessed as
vectors
typedef allocator<gate,
managed_shared_memory::segment_manager>gate_alloc;
typedef allocator<wire,
managed_shared_memory::segment_manager>inwire_alloc;
typedef allocator<wire,
managed_shared_memory::segment_manager>outwire_alloc;
//create a boost vector with an associated allocator to it
typedef vector<gate, gate_alloc>gate_vec;
typedef vector<wire, inwire_alloc>inwire_vec;
typedef vector<wire, outwire_alloc>outwire_vec;
//Initialize shared memory STL-compatible allocator
const gate_alloc alloc_inst(segment.get_segment_manager());
const inwire_alloc alloc_inst1(segment.get_segment_manager());
const outwire_alloc alloc_inst2(segment.get_segment_manager());
//construct the segment for pushing the data into it
gate_vec *gate_data = segment.construct<gate_vec>("gatedata")
(alloc_inst);
inwire_vec *inwire_data = segment.construct<inwire_vec>("inwiredata")
(alloc_inst1);
outwire_vec *outwire_data = segment.construct<outwire_vec>
("outwiredata")
(alloc_inst2);
//push the data into the vectors
wiredata.inGate = 10;
wiredata.inPin = 2;
wiredata.outGate = 1;
wiredata.outPin = 3;
inwire_data->push_back(wiredata);
outwire_data->push_back(wiredata);
gatedata.gateType = 1;
gatedata.inPins = 2;
gatedata.outPins = 3;
gate_data->push_back(gatedata);
real_T *y = ssGetOutputPortRealSignal(S,0); // the pointers vector
and use
y[0] = c->output(); // member functions of
the
} // object
/* Function: mdlTerminate
=====================================================
* Abstract:
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was
* allocated in mdlStart, this is the place to free it.
*/
static void mdlTerminate(SimStruct *S)
{
counter *c = (counter *) ssGetPWork(S)[0]; // retrieve and destroy C++
delete c; // object in the
termination
} // function
/*======================================================*
* See sfuntmpl_doc.c for the optional S-function methods *
*======================================================*/
/*=============================*
* Required S-function trailer *
*=============================*/
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file?*/
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
#ifdef __cplusplus
} // end of extern "C" scope
#endif
`
this is the sfunction which I have to mex , debug and run .Though the mexing of the above code snippet is successful ,it throws an exception "MATLAB.exe has triggered a breakpoint" while debugging.
I can give you an example. Unfortunately I cannot test it with windows, but I have tested it on a UNIX system. The main idea is the same. In this case it is shared memory from an external binary to a Matlab mex function.
The external binary is:
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
using namespace boost::interprocess;
const std::string payload("SHARED MEMORY CONTENT");
int main(void) {
shared_memory_object shm(open_or_create, "memory4mat" ,read_write);
shm.truncate(payload.size());
mapped_region mem(shm, read_write);
std::memcpy(mem.get_address(), payload.c_str(), mem.get_size());
do {
std::cout << '\n' << "Press a key to continue...";
} while (std::cin.get() != '\n');
shared_memory_object::remove("memory4mat");
return 0;
}
while the mex function is:
#include "mex.hpp"
#include "mexAdapter.hpp"
#include "MatlabDataArray.hpp"
#include <string>
#include <cstdlib>
#include "boost/interprocess/shared_memory_object.hpp"
#include "boost/interprocess/mapped_region.hpp"
using namespace boost::interprocess;
class MexFunction : public matlab::mex::Function {
public:
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
matlab::data::ArrayFactory factory;
shared_memory_object shm(open_only, "memory4mat", read_only);
mapped_region mem(shm, read_only);
std::string payload(static_cast<const char *>(mem.get_address()), mem.get_size());
outputs[0] = factory.createCharArray(payload);
outputs[1] = factory.createScalar<int16_t>(mem.get_size());
}
};
it uses the C++ Interface and Data API for Matlab. To compile the two example you need to add the boost include directory as compiler options (shared memory is a header only feature in boost).
The external binary create a shared memory that contains the string "SHARED MEMORY CONTENT", and waits an enter from the user to remove the shared memory object.
The mex files opens the shared memory if exist (if the shared memory do not exist an error is reported and handled in Matlab, which is one of the reasons why I prefer C++ api) and copy its content in a Matlab char array. The function returns two values, the first is the content of the shared memory, the second is the length of the shared memory (the mapper uses all the memory, set with truncate).
This simple example uses only basic features and should work on Unix and Windows system, but again I cannot test on win.
A more complete example
Let's try with a more complete example about shared memories and Matlab Mex files. Let us write a very simple external binary that allows us to create/delete/read/write a shared memory. This binary has a lot of stuff hardcoded for simplicity, such as the name of the memory file ("shmem"):
// File: share_server.cpp
// g++ share_server.cpp -o share_server
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
using namespace boost::interprocess;
static const std::size_t size = 20;
static const std::size_t wsize = 15;
static const char name[6] = "shmem";
static const char input[wsize] = "write in share";
char output[size];
inline void printHelp() {
std::cout << "Options:" << std::endl;
std::cout << " n) open a new 'shmem' memory" << std::endl;
std::cout << " d) delete a 'shmem' memory" << std::endl;
std::cout << " r) read from 'shmem' memory" << std::endl;
std::cout << " w) write to 'shmem' memory" << std::endl;
std::cout << " x) Exit" << std::endl;
}
inline void cmd_createShare() {
try {
shared_memory_object sm(create_only, name, read_write);
sm.truncate(size);
std::cout << "Shared object created" << std::endl;
} catch(std::exception & e) {
std::cout << "Create Error :: " << e.what() << std::endl;
}
}
inline void cmd_deleteShare() {
try {
shared_memory_object::remove(name);
std::cout << "Shared object deletetd" << std::endl;
} catch(std::exception & e) {
std::cout << "Delete Error:: " << e.what() << std::endl;
}
}
inline void cmd_readShare() {
try {
shared_memory_object sm(open_only, name, read_only);
mapped_region sh_mem(sm, read_only);
std::string ret(static_cast<const char *>(sh_mem.get_address()), sh_mem.get_size());
std::cout << ret << std::endl;
} catch(std::exception & e) {
std::cout << "Read Error:: " << e.what() << std::endl;
}
}
inline void cmd_writeShare() {
try {
shared_memory_object sm(open_only, name, read_write);
mapped_region sh_mem(sm, read_write);
std::memcpy(sh_mem.get_address(), input, wsize);
std::cout << "Write completed" << std::endl;
} catch(std::exception & e) {
std::cout << "Read Error:: " << e.what() << std::endl;
}
}
we can write 3 mex files (using the C++ api) in order to interact with the shared memory. The first one, the simplest, reads the content of the shared memory as a string and returns it to the Matlab workspace. The interface in Matlab syntax is something like:
function [value, read_size] = read_share(share_name)
...
end
and the C++ implementation is the following:
// File: read_share.cpp
#include "mex.hpp"
#include "mexAdapter.hpp"
#include "MatlabDataArray.hpp"
#include <string>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <exception>
#include "boost/interprocess/shared_memory_object.hpp"
#include "boost/interprocess/mapped_region.hpp"
using namespace boost::interprocess;
using namespace matlab::data;
class MexFunction : public matlab::mex::Function {
private:
std::shared_ptr<matlab::engine::MATLABEngine> engine;
ArrayFactory factory;
void throwError(std::string errorMessage) {
engine->feval(matlab::engine::convertUTF8StringToUTF16String("error"),
0, std::vector<Array>({ factory.createScalar(errorMessage) }));
}
uint64_t read_shared_memory(const std::string & name, std::string & ret_value) {
try {
shared_memory_object sm(open_only, name.c_str(), read_only);
mapped_region sh_mem(sm, read_only);
ret_value += std::string(static_cast<const char *>(sh_mem.get_address()), sh_mem.get_size());
return ret_value.size();
} catch(std::exception & e) {
throwError(std::string("Reading error: ") + std::string(e.what()));
}
return 0;
}
void checkArguments(matlab::mex::ArgumentList inputs, matlab::mex::ArgumentList outputs) {
if (inputs.size() != 1)
throwError("Input must be of size 1");
if (inputs[0].getType() != ArrayType::CHAR)
throwError("First element must be a matlab char array");
if (outputs.size() > 2)
throwError("Too many outputs (required 1)");
}
public:
MexFunction() {
engine = getEngine();
}
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
checkArguments(inputs, outputs);
const CharArray name_array = std::move(inputs[0]);
std::string name = name_array.toAscii();
std::string ret_string("");
uint64_t ret_size = read_shared_memory(name, ret_string);
outputs[0] = factory.createScalar(ret_string);
outputs[1] = factory.createScalar<uint64_t>(ret_size);
}
};
The second mex file is the write operation. It takes two input: the name of the shared memory and the string to write inside the memory. The mex checks the maximum size of the shared memory and stores no more than the available space. The function returns the bytes written in the The interface for the write function is something like:
function written_size = write_share(share_name, string)
...
end
and the implementation is:
// File: write_share.cpp
#include "mex.hpp"
#include "mexAdapter.hpp"
#include "MatlabDataArray.hpp"
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <exception>
#include "boost/interprocess/shared_memory_object.hpp"
#include "boost/interprocess/mapped_region.hpp"
using namespace boost::interprocess;
using namespace matlab::data;
class MexFunction : public matlab::mex::Function {
private:
std::shared_ptr<matlab::engine::MATLABEngine> engine;
ArrayFactory factory;
void throwError(std::string errorMessage) {
engine->feval(matlab::engine::convertUTF8StringToUTF16String("error"),
0, std::vector<Array>({ factory.createScalar(errorMessage) }));
}
uint64_t write_shared_memory(const std::string & name, const std::string & value) {
try {
shared_memory_object sm(open_only, name.c_str(), read_write);
mapped_region sh_mem(sm, read_write);
uint64_t size = std::min(value.size(), sh_mem.get_size());
std::memcpy(sh_mem.get_address(), value.c_str(), size);
return size;
} catch(std::exception & e) {
throwError(std::string("Reading error: ") + std::string(e.what()));
}
return 0;
}
void checkArguments(matlab::mex::ArgumentList inputs, matlab::mex::ArgumentList outputs) {
if (inputs.size() != 2)
throwError("Input must be of size 2");
if (inputs[0].getType() != ArrayType::CHAR)
throwError("First element must be a matlab char array");
if (inputs[1].getType() != ArrayType::CHAR)
throwError("Second element must be a matlab char array to save");
if (outputs.size() > 1)
throwError("Too many outputs (required 1)");
}
public:
MexFunction() {
engine = getEngine();
}
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
checkArguments(inputs, outputs);
const CharArray name_array = std::move(inputs[0]);
std::string name = name_array.toAscii();
const CharArray value_array = std::move(inputs[1]);
std::string value = value_array.toAscii();
uint64_t written = write_shared_memory(name, value);
outputs[0] = factory.createScalar<uint64_t>(written);
}
};
The last mex is the most complex and handles the creation and deletion of the shared memory. You will notice the presence of a destructor that handles the removal of shared memory when the mex is unloaded from Matlab. The interface takes a command in the form of "create" or "delete", a string with the name of the share and the size of the shared memory for creation (it must be an unsigned int - uint16(...)). The function returns the size of the shared memory (it should be equal to size):
function size_shmem = menage_mex(command, share_name, uint16(size))
...
end
the implementation is the following:
// File: menage_share.cpp
#include "mex.hpp"
#include "mexAdapter.hpp"
#include "MatlabDataArray.hpp"
#include <string>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <exception>
#include "boost/interprocess/shared_memory_object.hpp"
#include "boost/interprocess/mapped_region.hpp"
using namespace boost::interprocess;
using namespace matlab::data;
class MexFunction : public matlab::mex::Function {
private:
std::shared_ptr<matlab::engine::MATLABEngine> engine;
ArrayFactory factory;
std::vector<std::string> pool;
void throwError(std::string errorMessage) {
engine->feval(matlab::engine::convertUTF8StringToUTF16String("error"),
0, std::vector<Array>({ factory.createScalar(errorMessage) }));
}
uint64_t run_command(const std::string & cmd, const std::string & name, uint64_t size) {
if (cmd == "create")
return create_shared_memory(name, size);
if (cmd == "delete")
return delete_shared_memory(name, size);
throwError("The command is unknown");
return 0;
}
uint64_t create_shared_memory(const std::string & name, uint64_t size) {
bool in_pool = false;
for (const auto & el : pool) {
if (el == name) {
in_pool = true;
break;
}
}
if (in_pool) {
try {
shared_memory_object sm(open_only, name.c_str(), read_only);
mapped_region sm_reg(sm, read_only);
if (sm_reg.get_size() != size)
throwError("Memory already exist and it is of different size");
return 0;
} catch (std::exception & e) {
throwError(std::string("Cannot open existing shared memory (maybe already open?) :: ") + std::string(e.what()));
}
} else {
try {
shared_memory_object sm(create_only, name.c_str(), read_write);
sm.truncate(size);
pool.push_back(name);
return size;
} catch (std::exception & e) {
throwError(std::string("Cannot create shared memory [" + name + "] (maybe already open?) :: ") + std::string(e.what()));
}
}
return 0;
}
uint64_t delete_shared_memory(const std::string & name, uint64_t size) {
std::size_t in_pool = 0;
for (const auto & el : pool) {
if (el == name)
break;
in_pool++;
}
if (in_pool < pool.size()) {
shared_memory_object::remove(name.c_str());
pool.erase(pool.begin() + in_pool);
} else {
throwError("Shared memory [" + name + "] is not handled by this mex");
}
return 0;
}
void checkArguments(matlab::mex::ArgumentList inputs, matlab::mex::ArgumentList outputs) {
if (inputs.size() != 3)
throwError("Input must be of size 3");
if (inputs[0].getType() != ArrayType::CHAR)
throwError("First element must be a matlab char array");
if (inputs[1].getType() != ArrayType::CHAR)
throwError("Second element must be amatlab char array");
if (inputs[2].getType() != ArrayType::UINT64)
throwError("Third element must be a single uint64 integer");
if (outputs.size() > 1)
throwError("Too many outputs (required 1)");
}
void inputArguments(std::string & cmd, std::string & name, uint64_t & size, matlab::mex::ArgumentList inputs) {
const CharArray cmd_array = std::move(inputs[0]);
const CharArray name_array = std::move(inputs[1]);
const TypedArray<uint64_t> size_array = std::move(inputs[2]);
cmd = cmd_array.toAscii();
name = name_array.toAscii();
size = size_array[0];
}
public:
MexFunction() {
pool.clear();
engine = getEngine();
}
~MexFunction() {
for (const auto & el : pool) {
shared_memory_object::remove(el.c_str());
}
}
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
checkArguments(inputs, outputs);
std::string cmd, name;
uint64_t size;
inputArguments(cmd, name, size, inputs);
uint64_t ret = run_command(cmd, name, size);
outputs[0] = factory.createScalar<uint64_t>(ret);
}
};
To compile the mex you can use the following script:
MEX_OPT = ['-I', '/path/to/boost'];
MEX_SRC = { ...
'menage_share.cpp', ...
'read_share.cpp', ...
'write_share.cpp' ...
};
for i = 1:length(MEX_SRC)
mex(MEX_OPT, MEX_SRC{i});
end
!g++ share_server.cpp -o share_server
and you can test them as follows:
(MATLAB) | (TERMINAL)
>> menage_share('create', 'shmem', uint64(20)) |
<< 20 |
>> write_share('shmem', 'Hello there') | $ ./share_server
<< 11 | ( ... help message ... )
| << r
| >> Hello there
I have an assignment as following: Write a program will ask the user how many random numbers to generate. Then it will present a menu which has the options of Display, Average, Median, and Standard Deviation, Regenerate, and Quit. Without the use of a switch statement, or an if statements, or pointers to functions, have the program execute the user's selection from the menu. (Note: Function pointers are not allowed!)
This is what I have so far:
#include <iostream>
#include <cstdlib>
#include <array>
#include <cmath>
#include <stdlib.h>
#include <map>
using namespace std;
template <typename T> class wrapperclass
{
public:
static T myclass;
};
class Display
{
public:
static void myFunction(int random[], int num)
{
for(int i=0; i<num; ++i)
{
cout << random[i] <<endl;
}
}
};
class Average
{
public:
static double myFunction(int random[], int num)
{
double avg = 0;
for(int i=0; i<num; ++i)
{
avg += random[i];
}
return avg/num;
}
};
class Median
{
public:
static double myFunction(int random[], int num)
{
double mid = 0;
if(num % 2 == 0)
{
mid = (random[num/2] + random[num/2-1])/2;
}
else
{
mid = random[num/2];
}
return mid;
}
};
class StdDi
{
public:
static double myFunction(int random[], int num)
{
double avg=0;
double total=0;
for(int i=0; i<num; ++i)
{
avg += random[i];
}
avg = avg/num;
for(int i=0; i<num; ++i)
{
total += (avg-random[i])*(avg-random[i]);
}
total = total/num;
return sqrt(total);
}
};
class renerate
{
public:
static void myFunction(int)
{
}
};
class quit
{
public:
static void myFunction()
{
exit(EXIT_FAILURE);
}
};
int main()
{
int num = 0;
int option = 0;
map<int, class T> magic;
cout << "How many random numbers would u like to generate? " << endl;
cin >> num;
int random[num];
for(int i=0; i<num; ++i)
{
random[i] = rand() % 100 + 1;
}
cout << " Menu"<<endl
<< "1. Display"<<endl
<< "2. Average"<<endl
<< "3. Median"<<endl
<< "4. Standard Deviation"<<endl
<< "5. Renerate"<<endl
<< "6. Quit"<<endl;
cin >> option;
cout<<wrapperclass<Average>::myclass.myFunction(random, num);
return 0;
}
I'm about to directly pass the user input "option" into that "wrapperclass" like this "wrapperclass" so I can simply call the .myFunction since all classes have the same function name. but this won't work for c++ so is there any work around?
I have a class "PclProc" and I want to use std::sort.
I write a compare function in the same class because this comparing need the "in_ptr" which is a variable in the same class.
But as I did as following, there is always an error:
error: no matching function for call to
‘sort(std::vector::iterator, std::vector::iterator,
)’
std::sort(cloud_indice.indices.begin(),cloud_indice.indices.end(),PclProc::MyCompare);
bool PclProc::MyCompare(int id1, int id2)
{
return in_ptr->points[id1].z<in_ptr->points[id2].z;
}
float PclProc::MedianZDist(pcl::PointIndices cloud_indice)
{
std::sort(cloud_indice.indices.begin(),cloud_indice.indices.end(),PclProc::MyCompare);
int size=cloud_indice.indices.size();
float median_x,median_y;
...
Example of a functor being used for std::sort. vector D is the data, vector I is the indices to D. I is sorted according to D with std::sort using the functor. std::sort only creates one instance of class lessthan, then uses that one instance for all of the compares.
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <vector>
typedef unsigned int uint32_t;
#define SIZE 16
class example{
public:
std::vector<uint32_t> D; // data
std::vector<uint32_t> I; // indices
example(void)
{
D.resize(SIZE);
I.resize(SIZE);
for(uint32_t i = 0; i < SIZE; i++){
D[i] = rand()%100;
I[i] = i;
}
}
void displaydata(void)
{
for(size_t i = 0; i < SIZE; i++)
std::cout << std::setw(3) << D[I[i]];
std::cout << std::endl;
}
class lessthan // lessthan functor for std::sort
{
public:
const example &x;
lessthan(const example &e ) : x(e) { }
bool operator()(const uint32_t & i0, const uint32_t & i1)
{
return x.D[i0] < x.D[i1];
}
};
void sortindices(void)
{
std::sort(I.begin(), I.end(), lessthan(*this));
}
};
int main()
{
example x;
x.displaydata();
x.sortindices();
x.displaydata();
return 0;
}
#include <iostream>
#include <cmath>
using namespace std;
class point{ // define point class
private:
float x=0;
float y=0;
public:
point();// default constructor
point(float, float);// constructor
void setX(float);
void setY(float);
double getX()const;
double getY()const;
};
//implement all the member function
point::point(){ }
point::point(float i, float k){
x=i;
y=k;
}
void point::setX(float xc){
x=xc;
}
void point::setY(float yc){
y=yc;
}
double point::getY()const{
return y;
}
double point::getX()const{
return x;
}
double operator + (const point&lhs, const point &rhs) // free function.
{
double dx=lhs.getX()-rhs.getX();
double dy=lhs.getX()-rhs.getY();
return sqrt(dx*dx+dy*dy);
}
int main(){
point p1(2, -1);
point p2(1, 5);
int dist=0;
dist = p1 + p2;
cout << "The distance between p1 " << "and p2" << " is " << dist << endl;
return 0;
}
This should be 5 but I got 3. I do not understand why?
replace
double dy=lhs.getX()-rhs.getY();
by
double dy=lhs.getY()-rhs.getY()