I have a fairly basic program that is intended to sort a list of numbers via a Linked List.
Where I am getting hung up is when the element needs to be inserted at the beginning of the list. Here is the chunk of code in question
Assume that root->x = 15 and assume that the user inputs 12 when prompted:
void addNode(node *root)
{
int check = 0; //To break the loop
node *current = root; //Starts at the head of the linked list
node *temp = new node;
cout << "Enter a value for x" << endl;
cin >> temp->x;
cin.ignore(100,'\n');
if(temp->x < root->x)
{
cout << "first" << endl;
temp->next=root;
root=temp;
cout << root->x << " " << root->next->x; //Displays 12 15, the correct response
}
But if, after running this function, I try
cout << root->x;
Back in main(), it displays 15 again. So the code
root=temp;
is being lost once I leave the function. Now other changes to *root, such as adding another element to the LL and pointing root->next to it, are being carried over.
Suggestions?
This because you are setting the local node *root variable, you are not modifying the original root but just the parameter passed on stack.
To fix it you need to use a reference to pointer, eg:
void addNode(node*& root)
or a pointer to pointer:
void addNode(node **root)
Related
I am trying to print the contents of a String in a console application. I am doing a test and would like to visualize the content for debugging purposes.
Here is my code:
bool Tests::test001() {
std::string temp;
CDecoder decoder; // Create an instance of the CDecoder class
String input = "60000000190210703800000EC00000164593560001791662000000000000080000000002104302040235313531353135313531353153414C4535313030313233343536373831323334353637383930313233";
String expected_output = "6000000019";
String output = decoder.getTPDU(input); // Call the getTPDU method
std::cout << "Expected :" << expected_output.t_str() <<std::endl;
std::cout << "Obtained :" << output.t_str() <<std::endl;
return output == expected_output; // Return true if the output is as expected, false otherwise
}
This is what I get:
Running test: 0
Expected :024B8874
Obtained :00527226
Test Fail
Press any key to continue...
This is what I want to get:
Running test: 0
Expected :6000000019
Obtained :0000001902
Test Fail
Press any key to continue...
Here the Obtained value is a substring of the input I chose randomly (a shift to the left by two characters).
Whether I use t_str() or c_str() the result is the same.
In C++Builder 2009 and later, String (aka System::String) is an alias (ie, a typedef) for System::UnicodeString, which is a UTF-16 string type based on wchar_t on Windows and char16_t on other platforms.
Also, the UnicodeString::t_str() method has been deprecated since around C++Builder 2010. In modern versions, it just returns the same pointer as the UnicodeString::c_str() method.
You can't print a UnicodeString's characters using std::cout. You are getting memory addresses printed out instead of characters, because std::cout does not have an operator<< defined for wchar_t*/char16_t* pointers, but it does have one for void* pointers.
You need to use std::wcout instead, eg:
std::wcout << L"Expected :" << expected_output.c_str() << std::endl;
std::wcout << L"Obtained :" << output.c_str() << std::endl;
If you want to use std::cout, you will have to convert the String values to either System::UTF8String (and put the console into UTF-8 mode) or System::AnsiString instead, eg:
std::cout << "Expected :" << AnsiString(expected_output).c_str() << std::endl;
std::cout << "Obtained :" << AnsiString(output).c_str() << std::endl;
This seems to do the work:
std::wcout
Here is the working code:
// Member function to run test001
bool Tests::test001() {
std::string temp;
CDecoder decoder; // Create an instance of the CDecoder class
String input = "60000000190210703800000EC00000164593560001791662000000000000080000000002104302040235313531353135313531353153414C4535313030313233343536373831323334353637383930313233";
String expected_output = "6000000019";
String output = decoder.getTPDU(input); // Call the getTPDU method
std::wcout << "Expected: " << expected_output <<std::endl;
std::wcout << "Obtained: " << output <<std::endl;
return output == expected_output; // Return true if the output is as expected, false otherwise
I have a mongodb collection with the following document:
{
"_id" : ObjectId("5c879a2f277d8132d6707792"),
"a" : "133",
"b" : "daisy",
"c" : "abc"
}
When I run the following mongocxx code:
auto r = client["DB"]["Collection"].find_one({}).value().view();
isREmpty = r.empty();
rLength = r.length();
isOneInR = r.begin() == r.end();
for (bsoncxx::document::element ele : r) {
std::cout << "Got key" << std::endl;
}
I get isREmpty = false, rLength = 99, isOneInR = true and no output saying Got key.
I was expecting the print of "Got key" because one document returned from find_one.
Why isn't it showing?
You are viewing freed memory. The call to .value() creates a temporary bsoncxx::value object. You then get a view into that temporary object with .view() and attempt to examine the data, but it is too late.
What you want to do instead is capture the cursor returned by find_one:
auto cursor = client["DB"]["Collection"].find_one({});
Please see the examples for more details, but here is a quick example: https://github.com/mongodb/mongo-cxx-driver/blob/master/examples/mongocxx/query.cpp#L43
Lifetime management in the C++ driver requires attention. Please read the doc comments for the methods you use, as they will almost always describe the rules you must follow.
I'm currently developing an Answer Set Programming problem, consisting in a robot that is needed to cover a room avoiding obstacles and reach a Goal point when all the room is covered.
My idea was to transform the room map into asp predicates,in the form of room/3, being the parameters:
X:x coord
Y:y coord
V:Value of the point in the room, being 0(initial point),1(point to cover),2(Obstacle),3(Goal point)
One of the criteria that the program must meet is to cover every point with a value of 1,which can be achieved with a constraint, but I do not know how to model the robot movement. My idea was to use a predicate of the form move/1,with up,down,left or right.
Can anybody help me guiding me in how to model this problem?
void map_to_asp(std::ofstream& file,std::vector<std::vector<char>>& room)
{
std::cout << room.size() << "," << room[0].size() << std::endl;
for(int i = 0; i < room.size(); i++)
{
for(int j = 0;j < room[0].size(); j++)
{
switch(room[i][j])
{
case '#':
file << "initial(" << i+1 << "," << j+1 << ").\n";
break;
case '.':
file << "toClean(" << i+1 << "," << j+1 << ").\n";
break;
case '#':
file << "obstacle(" << i+1 << "," << j+1 << ").\n";
break;
case 'X':
file << "goal(" << i+1 << "," << j+1 << ").\n";
break;
}
}
}
}
Thank you in advance.
If your goal is to have a model for each possible path, a simple way to go is to make an iterative progression in the graph.
We need first to define all positions we can move in (we are actually building a graph before solving any problem):
position(X,Y,S):- room(X,Y,S) ; not S=2.
Now we decide where we can go from any position (edges of the graph):
edge((X,Y),(I,J)):- position(X,Y,_) ; position(I,J,_) ; |X-I|=0..1 ; |Y-J|=0..1 ; |X-I|+|Y-J|=1..2 .
Note that we consider that the graph is undirected (not necessarily true, if there is a slide in your room for instance).
Let's define some constants:
#const start_pos=(1,1).
#const goal=(5,5).
#const path_maxlen=100.
We obviously start at the starting point:
path(1,start_pos).
And now, we recursively indicate that there is a next way to go, with a limit to avoid too useless solutions.
0{path(N+1,E): path(N,S), edge(S,E), S!=goal}1:- path(N,_) ; N<path_maxlen.
We have to avoid all useless paths.
% a path that do not join the end is illegal.
:- path(N,E) ; not path(N+1,_) ; not E=goal.
% a path must go by all milestone (example of milestone: milestone(2,14)).
:- not path(_,(X,Y)): milestone(X,Y).
We want the shortest path:
last_step(N):- path(N,_) ; not path(N+1,_).
#minimize{N: last_step(N)}.
The full code is available here.
As a side-notes:
since we don't use them, you could (should) take rid of all room/3 that describe an obstacle.
you could also make you goal point artificial (out of the room, but the real goad is linked to it) in order to allow your path to pass by the real goal, without stopping. Using that, you can achieve support for multiple goal.
Good afternoon everybody,
In OpenCV I'm having trouble getting the VideoCapture's set function to change the frame rate. Here is my test program, using the "768x576.avi" test video file from the "C:\OpenCV-3.1.0\opencv\sources\samples\data" directory
// VideoCaptureSetTest.cpp
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#include<conio.h> // it may be necessary to change or remove this line if not using Windows
///////////////////////////////////////////////////////////////////////////////////////////////////
int main() {
cv::VideoCapture capVideo;
cv::Mat imgFrame;
capVideo.open("768x576.avi");
if (!capVideo.isOpened()) { // if unable to open video file
std::cout << "error reading video file" << std::endl << std::endl; // show error message
_getch(); // it may be necessary to change or remove this line if not using Windows
return(0); // and exit program
}
char chCheckForEscKey = 0;
double dblFPS = capVideo.get(CV_CAP_PROP_FPS);
std::cout << "1st time - dblFPS = " << dblFPS << "\n"; // this prints "10" to std out as expected
bool blnSetReturnValue = capVideo.set(CV_CAP_PROP_FPS, 5);
std::cout << "2nd time - dblFPS = " << dblFPS << "\n"; // this also prints "10", why not "5" as expected ??!!
std::cout << "blnSetReturnValue = " << blnSetReturnValue << std::endl; // this prints "0" (i.e. false)
while (chCheckForEscKey != 27) {
capVideo.read(imgFrame);
if (imgFrame.empty()) break;
cv::imshow("imgFrame", imgFrame);
chCheckForEscKey = cv::waitKey(1);
}
return(0);
}
I'm using a very standard setup here, OpenCV 3.1.0, Visual Studio 2015, Windows 10, and the .avi file I'm testing with is the one that ships with OpenCV.
No matter what I attempt to set the FPS to, it stays at 10 and the set function always returns false.
Yes, I'm aware of the hack fix of setting the cv::waitKey() parameter to a larger value to achieve a certain delay, but this would then be computer-dependent and I may need to run video on various computers in the future so this is not an option.
Am I doing something wrong? Is the VideoCapture::set function known to not work in some cases? Has anybody else experienced the same results? I checked the OpenCV issue tracker and did not find anything to this effect. Is this a bug I should raise a ticket for? Anybody else with some experience with this please advise.
Last semester in an assignment the class had to model a bank account in C++. This semester we are doing the same thing except in objective-c and in the form of an iOS app. I've just begun and have a basic storyboard set up to test my deposits however I cannot get my total balance to add up and I'm pretty sure it is because I instantiate my Account object with the deposit IBAction. How should this be done properly? I only need a push in the right direction and I'm confident I can hit the ground running from there with the rest. See attached code:
- (IBAction)deposit:(id)sender {
Account *acc =[[Account alloc]init];
double damount = [_textField.text doubleValue] ;
[acc deposit:(damount)];
_display.text = [NSString stringWithFormat:#"%f", acc.getBalance];
}
Original C++ code as requested:
int main(){
char szFName[32];
char szLName[32];
char szSIN[12];
char szAccType[10];
double dBalance;
int op;
Account *acc[MAX_ACCOUNTS];
int count=0;
while (count<MAX_ACCOUNTS)
{
cout << "Customer's First Name : " << flush;
cin >> szFName;
cout << "Customer's Last Name : " << flush;
cin >> szLName;
cout << "Customer's SIN : " << flush;
cin >> szSIN;
cout << "Account Type : " << flush;
cin >> szAccType;
cout << "Opening Balance : " << flush;
cin >> dBalance;
if ( !strcmp(szAccType,"Checking") )
acc[count] = new CheckingAcc(szFName, szLName, szSIN, szAccType, dBalance);
else if ( !strcmp(szAccType,"VIP") )
acc[count] = new VIPAcc(szFName, szLName, szSIN, szAccType, dBalance);
else if ( !strcmp(szAccType,"Saving") )
acc[count] = new SavingAcc(szFName, szLName, szSIN, szAccType, dBalance);
else
{
cout << "Incorect account type." << endl;
continue;
}
count++;
}
The problem you're facing is that you're creating a new bank account every time instead of maintaining a single account and adding to it.
In your original program you created an array of accounts acc that persisted during the lifetime of the user input. Since you've moved from a procedural program to a UI program with a run loop, you'll need a more persistent place to store it.
Generally, a good spot would be a property on your view controller or higher up if the objects need to persist longer than the view controller:
#property Account *account;
...
- (id)init
{
if (self) {
_account = [[Account alloc] init];
}
return self;
}
...
[self.account deposit:(damount)];
Since this is for class, you will probably want to review your textbook for topics like properties and instance variables.