QT printing binary tree instruction messages - c++

I am having an issue trying to display correct debugging messages in my GUI on qt. I am implementing a binary tree based on words that are entered by a user. And for each word that is entered an appropriate debugging message should display.
For example:
user enters : a
then user enters b
debugging message word is greater than a
The problem that I am having is that if the user was to then type a third word in the debugging message is incorrect.
user enters c
debugging message still displays as word is greater than a
But I would like it to display word is greater than b instead.
If the user inputs a duplicate word the message should display 'word' has already been detected. This message only works if its the original word that the user has entered and is duplicating. For the example above if the user enters a again the correct message appears. If they enter b again the duplicate message does not appear.
How can I fix this?
QStringList tree::VerboseModeinsert(NodePtr &ptr, QString aWord)
{
aWord.remove(QRegExp("[[]"));
aWord.remove(QRegExp("[]]"));
if(!(aWord.contains(QRegExp("[0123456789]"))))
{
aWord = aWord.toLower();
if(ptr != NULL)
{
if(aWord < ptr->word)
{
insert(ptr->below, aWord);
QString a = "Word is less than ";
QString b = ptr->word;
verboseList << a + b;
}
else if(aWord > ptr->word)
{
insert(ptr->above, aWord);
QString a = "Word is greater than ";
QString b = ptr->word;
verboseList << a + b;
}
else
{
ptr->occurence++;
QString c = " has already been detected";
verboseList << aWord + c;
}
}
else
{
ptr = new WordTree;
ptr->word = aWord;
ptr->below = NULL;
ptr->above = NULL;
ptr->occurence = 1;
}
}
return verboseList;
}

Seems you forgot to update the pointer to the last inserted,
Try this:
...
if(aWord < ptr->word)
{
...
ptr = ptr->below;
}
else if(aWord > ptr->word)
{
...
ptr = ptr->above;
}
...
PS: I'm not completly sure what I'm doing beacause you don'n provide a MCVE, but I think the post is suficient to infer that you are not changing the pointer to the last inserted.

Related

"Update" line in CMD, C++

I need to get input from the user but if an invalid argument is passed in then the "Invalid" messages stack up.
I'd prefer if it just kept printing the invalid on the same line and then once a correct input is given it resets the line to original question.
I've seen the talk of using \r but it does not seem to work for me.
bool getInput(std::variant<std::string, float>* toOut, bool* restart, bool* qUsed){
std::string userIn;
std::cin >> userIn;
if(userIn == SENTINAL){
*restart = true;
return false;
}
try {
*toOut = std::stof(userIn);
} catch(std::invalid_argument) {
if(userIn == TO_SOLVE && !*qUsed){
*toOut = TO_SOLVE;
*qUsed = true;
} else {
std::cout << "\rInvalid, please try again : ";
getInput(toOut, restart, qUsed);
}
}
return true;
}
I haven't put the resetting to original question yet.
When I run this the \r does nothing.
Why is this / what's the best way to "update" cmd text?

Program returning blinking Cursor

So im doing a sort Method using the bubble sort and compareTo method
Yet for some reason, when I run the program it compiles, does no errors whatsoever and shows a blinking cursor in the program (as if u are about to type something in; which u can, just when u press enter nothing happens) and this cursor keeps blinking.
What's wrong here ? (code based on teacher's instructions)
public static void sort(ArrayList al)
{
Person p,p1,p2;
String a1,a2;
boolean flag = true;
System.out.println("Database will be sorted acc to ID ");
System.out.println();
do
{
flag = false;
for (int i=0;i<al.size()-1;i++)
{
p = (Person)al.get(i);
a1=((Person)al.get(i)).personID;
a2=((Person)al.get(i+1)).personID;
if (a1.compareTo(a2) > 0){
p1= (Person)al.get(i);
p2 =(Person)al.get(i+1);
}
}
}
while (flag = true);
if (flag = false)
{
for (int i = 0; i < al.size(); i++)
{
p = (Person) al.get(i);
System.out.println("----------" + (i+1) + "-----------");
System.out.println("ID Number: "+ p.personID);
System.out.println("Name: "+ p.name);
System.out.println("Day of Birth: " +p.dayDOB);
System.out.println("Month of Birth: " +p.monthDOB);
System.out.println("Year of Birth: " +p.yearDOB);
System.out.println("Telephone Number: " +p.telNum);
System.out.println("");
}
}
The problem is in this loop:
do
{
....
}
while (flag = true);
You want to compare flag to true, i.e. flag == true, but instead you set flag to true with flag = true. Therefore, the loop will not exit, but instead run forever (or until you terminate the program).
You have the same problem in the following if statement.

C++: Updating binary search tree using a recursive search function?

I'm in the middle of making a binary search tree that stores Items of type MechPart, which stores an int quantity and a string code. The MechParts are generated by reading from a text file and storing their data. A separate text file called MonthlyUpdate.txt is used to read a list of MechParts in the tree and then update their quantities. For example:
MechPart A0001's quantity = 12
MonthlyUpdate.txt says A0001's quantity = 6
Run an update function that finds A0001 in the tree
Replace it with the updated quantity value of 6 (12 - 6).
Here's the two functions that perform this task:
void DBInterface::updateFromFile(string f_Name)
{
ifstream file (f_Name.c_str());
string line;
MechPart tmp_mp;
if (file.is_open())
{
std::getline(file, line);
while (std::getline (file, line))
{
std::istringstream iss (line);
int q=0;
int pos=0;
pos = line.find('\t',0); //find position of blank space
string tmp_str = line.substr(0,pos); //create a substring
string tmp_str1 = line.substr((pos+1), string::npos);
stringstream ss (tmp_str1);
ss >> q;
tmp_mp.set_code(tmp_str); //set code
tmp_mp.set_quantity(q);
MechPart currentQuantity;
currentQuantity = tree.quantitySearch(tree.getRoot(), tmp_mp);
tmp_mp.set_quantity((currentQuantity.get_quantity()) + q);
tree.update(tree.getRoot(), tmp_mp);
cout << "Current node data: " << tmp_mp.get_code() << " | " << tmp_mp.get_quantity() << endl;
}
}
and BSTree.template:
template <typename Item>
Item BSTree<Item>::quantitySearch(BTNode<Item>* q_ptr, Item obj)
{
if (q_ptr == NULL)
{
//POINTER IS NULL
}
else if (q_ptr->data() == obj)
{
return q_ptr->data();
}
else if (obj > q_ptr->data())
{ //WORK ON RIGHT SIDE
quantitySearch(q_ptr->get_right(), obj);
}
else
{
//work on left side
quantitySearch(q_ptr->get_left(), obj);
}
}
The search goes through the tree and locates a MechPart with the same part name code as the parameter and then returns that MechPart.
I've been running the code through GDB debugger. I have it displaying currentQuantity.get_quantity() to validate the returned MechPart's quantity is correct, however i am getting very large numbers for some reason. What is also confusing me is that in the MechPart constructor it assigns a value of 0 to quantity.
Eventually the updateFromFile() function gives me a segmentation fault, so something is very wrong here but I can't work out what as yet.
Recursive functions need to return their recursive calls back up to their caller for them to work properly. Look at the classic factorial example of recursion:
int factorial(int n) {
if (n == 1) {
return 1;
}
else {
return n*factorial(n-1);
}
}
As others have pointed out, your quantitySearch function only returns q_ptr->data() but never returns the return value from the recursive quantitySearch calls. I would start there and I would strongly suggest adding in cout statements in the recursive function to get a complete picture of what's happening "under the hood"

Qtvector content modification not happening

I have a struct functionStruct and a QVector<functionStruct> . I am doing following..
when I click on a button the slot calls this function.
when I click 1st time it prints "somedoc" (expected)
but when I click 2nd time (and onwards) it prints nothing ( member is null)
int s = 0;
void foo()
{
if(!s) {
functionStruct *newp = new functionStruct;
functionStruct old = function_list.at(0);
newp->function_string.append(old.function_string);
newp->start = old.start;
newp->function_doc = "somedoc";
function_list.replace(0,*newp);
s = 1;
}
qDebug() << "pd0 contents " << function_list.at(0).function_doc
}

Segmentation Fault : 11 when popping a vector in C++

I would ideally like to use one stack in this program but it doesn't let me. I keep getting a segment error 11. I got around this sort of by making a new vector and setting that equal to the first vector and then poping the new vector. But I eventually need to sync the popped vector up with the first vector but it throws a segment error 11.
anyway here is the code, its part of another project but I dont think the context is too important to know what its for. Also this does compile its just when I run this method it throws the error.
void print_well_formed_file(ifstream& ifs) {
vector<string> vec;
vector<string> finalVec;
string line;
string a;
string temp;
string final;
Lexer lexer;
Token tok;
while (getline(ifs, line)) {
lexer.set_input(line);
while (lexer.has_more_token()) {
tok = lexer.next_token();
switch (tok.type) {
case TAG:
if (tok.value[0] != '/'){
a = (tok.value);
if (a == "red") {
a = "\033[31m";
}
if (a == "green") {
a = "\033[32m";
}
if (a == "blue") {
a = "\033[34m";
}
if (a == "yellow") {
a = "\033[33m";
}
if (a == "magenta") {
a = "\033[31m";
}
if (a == "cyan") {
a = "\033[36m";
}
if (a == "dim") {
a = "\033[2m";
}
if (a == "underline") {
a = "\033[4m";
}
if (a == "bright") {
a = "\033[1m";
}
vec.push_back(a);
final = temp + a;
}
else{
string s;
string temp;
string fin;
finalVec = vec;
if(!finalVec.empty()){finalVec.pop_back();}
a = "\033[0m" + finalVec.back();
temp = final;
final = temp + a;
if(!vec.empty()){vec.pop_back();} // throws an error
vec = finalVec; // throws an error
}
break;
case IDENT:
a= (tok.value)+ " ";
temp = final;
final = temp + a;
break;
}
}
}
cout << final << endl;
}
You cannot pop or get an element from an empty vector. It's undefined behaviour, and it will likely crash your app.
You can verify that this is the problem by checking the length before each access in your code (you just "randomly" picked one of the locations in your latest update). Look, it's really simple.. just display an error message if it's empty.
if(!finalVec.empty()){finalVec.pop_back();}
a = "\033[0m" + finalVec.back(); // <-- bug
is obviously buggy: finalVec.back() may not exist: since the last element has just been popped the vector may be empty.