not working function with no errors - c++

I've implemented a function to display an avl tree after inserting nodes into it like this
template<class nodetype>
void AVLtree<nodetype>::display() const
{
display(Proot);
}
template<class nodetype>
void AVLtree<nodetype>::display(Node<nodetype> * ptr) const
{
if(ptr==0)
return ;
cout<<ptr->value<<" ";
display(ptr->Pleft);
display(ptr->Pright);
}
after compiling,there were no errors ,the program worked but nothing were printed on the screen
help me please....!!
thanks

(Assuming that your tree is built correctly). Screen output is normally line-buffered. You need to output std::endl to std::cout (or at least '\n' character) for something to appear on the screen.
Of course, if your tree is built incorrectly, the root pointer might be null and nothing would be printed for obvious reasons (just a guess).
Finally, even if your tree is built correctly, but all data (ptr->value) is, say, just strings that are empty (for example) or contain only whitespace, then no wonder you can't see anything on the screen.

One technique I like to use is to add delimiters around debug strings:
cout << "-->" << ptr->value << "<--" << endl;
That way, it's easy to distinguish empty output from no output.
You may also want to add something that shows when your entire tree is empty:
void AVLtree<nodetype>::display() const
{
if (Proot)
display(Proot);
else
cout << "empty tree" << endl;
}

If you are printing on a console window, this function may be of use:
void Pause(void)
{
cout << "\nPaused, press ENTER to continue.\n";
cin.ignore(10000, '\n');
return;
}
Call this function before any exit methods or return statements in main.

first of all you need a conceptual overhaul.. Who told you you can compare ptr with 0 ?
Are you trying to suggest that a pointer if nullified is equal to 0 ? Thats totally wrong .. try this :
#include<iostream>
#include<conio.h>
using namespace std;
int main () {
int *p = NULL ;
cout<<*p<<endl;
getch();
return 0;
}
and there your program crashes ... compare ptr with NULL instead of 0 ..

Related

What would std::cout before calling my function do in this case?

#include <iostream>
// **Change needs_it_support so that it returns support:**
bool needs_it_support() {
bool support;
std::cout << "Hello. IT. Have you tried turning it off and on again? Enter 1 for yes, 0 for no.\n";
std::cin >> support;
return support;
}
int main() {
// **Change the following line to print the function result:**
needs_it_support();
}
I understand that to make this work the way I want to, I would have to do:
std::cout << (call my function)
But, my question is, what does that do? Wouldn't that just execute all my code and try to output it to the console, and then obviously give me errors? Or, does it only output specific things?
std::cout << needs_it_support()
This will call needs_it_support() first, and then pass its bool return value to operator<<. It is essentially calling:
std::cout.operator<<(needs_it_support())
So, whatever bool value needs_it_support() returns, that is what will be printed to the console (in addition to anything else that needs_it_support() itself prints internally).

Recursive Function Error1

I am making a program that the user inputs integers and outputs them in reverse. It is a recursive function. The Problem now is that it outputs an infinite of 0's. Please tell me where is the error in my code. and I need some pointers. Please help.
#include <iostream>
using namespace std;
void printreverse(int);
int main()
{
int x;
cout << "Enter numbers: ";
cin >> x;
printreverse(x);
return 0;
}
void printreverse(int x)
{
if(x<10)
cout << x;
else
cout << x%10;
printreverse(x/10);
}
You have wrong identing in printreverse. It should be like this:
void printreverse(int x)
{
if(x<10)
cout << x;
else
cout << x%10;
printreverse(x/10);
}
First it prints x or x%10, then it recurses regardless of what x is. If you wanted more than one statement done in a consequent or alternative you need to use a block. Blocks are denoted with {} in C-decendants. They are so usual that some people actually think conditionals and control flow syntax need to have them. Anyway if the identing was the intended behaviour you should write it like:
void printreverse(int x)
{
if(x<10) {
cout << x;
} else {
cout << x%10;
printreverse(x/10);
}
}
Whenever I use braces on one term in an if I add them for every one even when it's not really needed. Some coding standards, like PSR2, require blocks always to remove the chance of ever getting bugs like this.
C++ is not Python. You need to surround your else block by braces, like so
else
{ // need brace here
cout << x%10;
printreverse(x/10);
} // and here
otherwise only the first statement after the else is being executed (and the final printreverse(x/10) will always be executed, even for 0, so you end up overflowing the stack).
I recommend you to always put braces, even for a single statement in an if/else, precisely for reasons similar to the one you just bumped into.

Program throwing exception

I am writing a program that allows the user to enter a sentence which then gets stored in a string and then the program will remove any full stops in the sentence and then create a list of each individual word in the string before outputting that list to the console.
the program is working perfectly as long as there is only 1 full stop in the sentence but if there are any more than that it throws this exception:
Unhandled exception at at 0x7696B727 in Project6.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0022F8B8.
and then if I continue to run it it throws:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
any suggestions? (and before anyone asks, i know you usually only have 1 full stop in a sentence but i need to do it with more than 1 as part of testing.
here is the code:
#include <iostream>
#include <string>
using namespace std
string sSentence; // sets up a string variable called sSentence
int i = 0;
void RemoveFullStop()
{
while(sSentence.find (".") != string::npos) // the program runs this loop until it cannot find any more full stops in the string
{
i = sSentence.find("." , i); // find the next full stop in the string and get the character count of the space and place it in the variable i
sSentence.replace(i,1,""); // remove the full stop
}
}
void ListWords()
{
while(sSentence.find (" ") != string::npos) // the program runs this loop until it cannot find any more spaces in the string
{
i = sSentence.find(" " , i); // find the next space in the string and get the character count of the space and place it in the variable i
// cout << i << endl; // output the contents of iWordSpace to the console (used for debugging - no longer used)
sSentence.replace(i,1,"\n");
// cout << sSentence << endl; // output the contents of iWordSpace to the console (used for debugging - no longer used)
}
}
int main()
{
getline(cin, sSentence); // get user input and store it in sSentence (using the getline function so the .find operation works correctly)
RemoveFullStop(); // calls the RemoveFullStop void function that removes all full stops from the string
ListWords(); // calls the ListWords void function that splits the string into a list of words
cout << endl; // formatting line
cout << "The words that were in the sentence were:" << endl;
cout << endl; // formatting line
cout << sSentence << endl;
cout << endl; // formatting line
system("pause");
return 0;
}
The problem is that you keep re-using i, in both RemoveFullStop and ListWords.
i only ever increases, and so eventually it can get past the end of the string.
You really shouldn't need a global i variable at all, to do this task.
The reason this happens is that when sSentence.find(" " , i) in ListWords runs, i's value is not 0 because it was already defined in RemoveFullStop(). To fix this, first remove int i = 0;, then add it to RemoveFullStop() and ListWords()
Also, while this is just a style thing and won't effect your codes ability to run, I wouldn't call this variable i as i,j,k usually imply counters. Call this variable something more appropriately descriptive.
Here is the relevant code as it should be.
using namespace std
string sSentence;
void RemoveFullStop()
{
int charPlace = 0;
while(sSentence.find (".") != string::npos)
{
charPlace = sSentence.find("." , charPlace);
sSentence.replace(charPlace,1,"");
}
}
void ListWords()
{
int charPlace = 0;
while(sSentence.find (" ") != string::npos)
{
charPlace = sSentence.find(" " , charPlace);
sSentence.replace(charPlace,1,"\n");
}
}

Why does it say that my 'destroystack' isn't declared?

#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main()
{
string name;
double gpa;
double high = 0;
stack<string>names;
for (int i=0;i<7;i++)
{
cout << " Enter student's name and gpa " <<endl;
cin >> gpa ;
cin >> name ;
if (gpa > high)
{
names.destroyStack();
high = gpa;
names.push(name);
}
else
if (gpa==high)
{
names.push(name);
}
}
cout << "Highest gpa is " << high << "Names with the highest gpa are"<< endl;
while (!names.empty)
{
cout << names.top() << endl;
names.pop();
}
return 0;
}
In order to display only the names with the highest gpa, I have to put a code to remove the stack before with the lower gpa scores.So for this I thought I could use the "destroystack()" operation but when I use that and try and execute it, the compiler says that the destroyStack wasn't declared in the scope.
This AND the bottom one where I want to display the stack.It even says that empty wasn't declared.
I'm confused with these errors and I don't know what it means by declaring the operations? I'm using codeblocks (Not Visual studio) so does that affect anything?
Because, quite simply, there is no such function destroyStack in std::stack. I have no idea where you got the idea that there is.
This code should work to empty your stack:
replace:
names.destroyStack();
with:
while (!names.empty())
{
names.pop();
}
As you can see, empty is a function; it returns a value. In this case, it returns a boolean (true/false), so you'll need to have parenthesis after it, in order to call it.
That's why you're getting the message about empty not being declared; it means that the compiler is looking for a variable called empty, but it doesn't exist. By adding the parens, you're telling it that you want to call a function, not access a variable.
The "while loop" iterates through all of the items in the stack until the stack is empty. This effectively means that, for every item that the stack has in it, the item is "pop'd" off (pop is also a function, but it returns the item that was on the stack). Eventually, the stack has nothing left in it, and the while loop exits, because empty() returns true.
For a good reference on what functions and properties the stack template has on it, check out:
http://www.cppreference.com/wiki/container/stack/start
You should implement that destroyStack yourself. A function such as:
void destroyStack(stack<string>& _stack)
{
// Do whatever
}
And call it with:
destroyStack(names);
empty should be empty() instead.
Your editor, codeblocks or Visual Studio, doesn't affect anything.

Weird segmentation fault errors

Ok, so im working on an assignment and for the life of me I cannot figure out why I am getting these segmentation faults. Im still in the process of learning c++, programming in general, so I was hoping someone wiser than me can help me out. The program is a self organizing binary search tree and I wasn't having too much difficulty with it until now. Here is the beginning of a main program I am using to test my class BST, I cannot alter the mian program since it is an assignment.
int main() {
string input;
// get a list of integer values
cout << "Enter a list of integer values in one line: ";
getline(cin, input);
cout << "\n**CHECKPOINT 1**\n";
// create a binary search tree
BST<int> bst1(input);
if (!bst1.empty()) {
cout << "\n**CHECKPOINT 2**\n";
cout << "Inorder traversal: ";
bst1.printInOrder();
cout << "Level order traversal: ";
bst1.printLevelOrder();
I have yet to get past the printInOrder() function, here is the code for that
template <typename T>
void BST<T>::printInOrder(BSTNode* t) const
{
if (t->left != NULL)
printInOrder(t->left);
std::cout << " " << t->data << " ";
if (t->right != NULL)
printInOrder(t->right);
}
The really strange thing that is confusing me if that when I add a quick cout<< "Something" to the first line of the printInOrder function, it all of a suddent will the print line
cout << "Inorder traversal: ";
and it will also start printing some of the numbers in the tree before finally giving me a segmentation fault again. :/
So, I would be really grateful if someone could explain to me WTF is going on. The adding or subtracting of a simple cout line shouldn't change things like that should it? Also, I feel like there are better ways of debugging this, if anyone has techniques that they use to figure this stuff out, please share :) Thanks in advance!
EDIT: I have tried the debugger GDB, I was unable to figure it out, but then again im not very well versed in the advanced features of debuggers so I might have missed something.
The only other function that is even run, is the constructor to build from the string input. From what I could tell from the debugger is that the constructor seems to be working fine but nonetheless here's the code
template <typename T>
BST<T>::BST(const std::string input, int th)
{
threshold = th;
root = NULL;
T v;
// Make Input String Stream for easy use of >> operator
std::istringstream iss (input);
do
{
iss >> v;
insert(v, root);
}while(iss.good());
}
EDIT2:
Here is the code for my insert function, Thanks for the help everybody! :)
template <typename T>
void BST<T>::insert(const T& v, BSTNode *&t)
{
if(t == NULL)
{
t = new BSTNode;
t->left = NULL;
t->right = NULL;
t->data = v;
t->searchCount = 0;
}
else if( v < t->data )
insert(v, t->left);
else
insert(v, t->right);
}
There's a marked lack of newlines in your output. Often the line buffering means you don't see anything until a newline is encountered.
I'd modify the line after the PrintOnOrder to this:-
cout << "\nLevel order traversal: ";
In the constructor you are inserting v into the tree even if reading the data with iss >> v failed. Probably you rather want something like this:
while (iss >> v) {
insert(v, root);
}
But probably the real cause for your segmentation fault lies in insert(), for example if that function just inserts a pointer to the (stack allocated) parameter it receives into the tree. The parameter variable will go out of scope at the end of the function (and therefore cease to exist). If you just stored a pointer to that variable into the tree, that pointer will no longer point to anything useful.
I don't see anything wrong here. As others pointed out, output buffering may mean that your code actually completes printInOrder() successfully and then crashes somewhere later.