Tom Gunn 1,164 Practically a Master Poster

(which will ensure a cast to an unsigned long, the biggest unsigned integral type)

Unless size_t is unsigned long or integral promotion makes it an unsigned long, the only thing you ensure is undefined behavior because the type of the value and the type of the format string do not match. The convention is to use an explicit cast:

printf("%lu\n", (unsigned long)sizeof(something));

to make sure that the size will always be displayed correctly on the screen.

If you are lucky. size_t is only guaranteed to be unsigned. It might be an extended type, where there is risk of the value being truncated by casting to unsigned long. The ideal solution is C99's %z modifier:

printf("%zu\n", sizeof(something));

But for C89 compilers the best we can do is cast to the largest possible unsigned type that printf() supports and hope for the best. :)

tux4life commented: Thanks for the very useful addition :) +23
Tom Gunn 1,164 Practically a Master Poster

I can get it to save and load but when I try displaying it, its gonna have a General Protection Exception error.

Your data structure is probably getting corrupted during the load. Maybe you are not terminating one of the lists with NULL, or not handling NULL cells as a special case and trying to dereference them. The best way to troubleshoot is to find a small case that fails and step through it with a debugger while watching your memory for changes.

Tom Gunn 1,164 Practically a Master Poster

Not that I can remember. But they are easy to write, so it is not a big loss. :)

Tom Gunn 1,164 Practically a Master Poster

1) Using the getchar() function, you need to flush the input buffer to get rid of the newline character

As a corollary, fflush(stdin) is not the way to flush the input buffer because fflush() is only defined to work on output buffers. A portable way to flush is getchar() in a loop:

while (getchar() != '\n')
{
    /* no work to do */
}

If EOF is possible, add that to the condition:

{
    int c;

    while ((c = getchar()) != '\n' && c != EOF)
    {
        /* no work to do */
    }
}

The only problem with this loop strategy is when the buffer is empty, the loop will block until some characters are buffered. The end user will have to type an extra [Enter] before getting past the loop, and that can be surprising. I like to fix it by dipping into the stream internals, but that is not a portable fix. Use it with caution:

#if defined(_MSC_VER)
/* Visual C and derivatives */
#define FLUSH_STDIN() stdin->_cnt = 0;
#else
#define FLUSH_STDIN() while (getchar() != '\n')
#endif

2) In your original code posting, you used void main() - this is bad, very bad.

I have only seen one OS mentioned that fails when void main() is used, and both compilers in that article warn about it. Not recommended, definitely. void main() is not portable and technically undefined when the compiler does not support it, so it should be avoided on all hosted …

kvprajapati commented: Thanks Tom to share your knowledge. Good suggestion but I still recomend int main() +17
tux4life commented: I still prefer to use the standard about the return type of main, but you're right about the void main() :) +23
Tom Gunn 1,164 Practically a Master Poster

i have wriitten the following code and checked for five levels its working fine. but i am not comparing the values of the nodes.

is it the correct way ?

That should work. So your definition of a strict tree is where each node has either 0 or 2 children?

Tom Gunn 1,164 Practically a Master Poster

but i dont understand how can we ensure a binary tree is strict just by checking only root and its children .

That was my mistake. I posted an incomplete example. That function is supposed to be recursive. I will try again:

int IsStrictRoot(struct node* root)
{
    return !((root->left && root->left->dat >= root->dat) ||
             (root->right && root->right->dat <= root->dat));
}

int IsStrictBst(struct node* root)
{
    if (root)
    {
        return IsStrictBst(root->left) && 
               IsStrictBst(root->right) && 
               IsStrictRoot(root);
    }
    else return 1;
}

The rule for a strict binary search tree is that the left node has a smaller value than the root and the right node has a larger value than the root. That is assuming no duplicate values are allowed in the tree. The comparison can be changed to support that duplicates easily. :)

for the tree to be strict does it must be a BST?

For a tree to be strict you need to define what strict is. A BST has a node order requirement, but if you have a binary tree that is not a BST, there has to be some ordering that makes it strict, or the design of the tree allows more than one child node and you want to allow only up to two at run time.

but you checked it reverse.

It is a reverse test for failure. Here is the truth table for that comparison:

I = Invalid
V = Valid
* = NULL

   | * | V | I | …
tux4life commented: Is there maybe something you don't know? :P +22
Tom Gunn 1,164 Practically a Master Poster

Can you modify the code sir? Or just tell me the instructions.

You have the range() function done since I wrote it for you, and I gave you an idea of how to change your main() function, but if I give you the code you will not learn as much as working your way through something you do not understand. You would have to learn that lesson at some point anyway, so it might as well be now. :)

Tom Gunn 1,164 Practically a Master Poster

Would anyone like to share their tips & tricks for debugging functions & whole programs in C++.

Learn how your computer works! :) I found that understanding the machine and things at a lower level like assembly and how the OS manages programs/memory really helped my debugging. It also helped improve the quality of my code.

Tom Gunn 1,164 Practically a Master Poster

The problem is that its output is incorrect. It outputs wrong count of the numbers.

in only holds a single value at any time. When the loop ends, in contains the last value you typed and all of the others were thrown away. in should be an array if you want to work with a list of values, and each of the range() functions should loop through the array checking for values in the expected range.

But since you do the same thing in each range() function just with a different range, you can roll it all up into one function:

/* count values in the range of [lo..hi] */
int CountInRange(int a[], int sz, int lo, int hi)
{
    int x, cnt = 0;

    for (x = 0; x < sz; ++x)
    {
        if (a[x] >= lo && a[x] <= hi) ++cnt;
    }

    return cnt;
}
Tom Gunn 1,164 Practically a Master Poster

When you say 'strict binary tree', you mean that each node has only two links? You can do it, but if your node struct only has left and right pointers, it is kind of pointless to do a test that is guaranteed at design time. ;)

If you mean to test for a strict binary search tree, you need to do a key value relation test:

int IsStrictBst(struct node* root)
{
    if (root)
    {
        if ((root->left && root->left->dat >= root->dat) ||
            (root->right && root->right->dat <= root->dat))
        {
            return 0;
        }
    }
    else return 1;
}
Tom Gunn 1,164 Practically a Master Poster

C does not support nested functions. You need to move the function definitions outside of main().

Tom Gunn 1,164 Practically a Master Poster

I cannot say what the problem is without more code to test with, but it might be that your runtime is not flushing stdout. Try printing a '\n' character or calling fflush(stdout) after the fwrite() to force a flush.

Tom Gunn 1,164 Practically a Master Poster

Is this possible that instead of typing - program.week[0].workout[0].exercise[0].exerciseName
everytime I want to access an element.
That I can access the elements of the most nested struct via a pointer.

Yes. If you have an object, you can have a pointer to it:

#include <stdio.h>

struct A
{
    struct B
    {
        struct C
        {
            int dat;
        } c;
    } b;
};

int main()
{
    struct A a;
    struct C* pc = &a.b.c;

    pc->dat = 123;
    printf("through struct pointer: %d\n", pc->dat);
    printf("direct access:          %d\n", a.b.c.dat);

    return 0;
}

Is that what you were trying to do?

Tom Gunn 1,164 Practically a Master Poster

Then it is getting set to null somewhere. Maybe you have a buffer overflow somewhere, or some other memory corruption that is blowing up at that point. Memory errors are the hardest to debug, so you might be stuck with stepping through your code and watching that pointer until you find the cause.

Tom Gunn 1,164 Practically a Master Poster

Assuming the input buffer you are testing is the same input buffer that was allocated, the only thing that stands out in the code you posted is this:

inputBuffer->inputPriorityList = createList(inputBufferName) ;

createList() might be returning a null pointer in some cases.

Tom Gunn 1,164 Practically a Master Poster

Good start! C is different in a few ways though. Declarations need to be the first thing in a block unless you are compiling under C99, so your C code will not compile with most compilers.

printf("N %2.2f, factorial %2.2f \n" ,i,factorial(i));

You need to be very careful with printf() and scanf() format strings because mixing up types can give weird results. In this one, the first modifier should be %d, not %2.2f, because i is an int.

char wait;
printf("Enter to exit");
scanf(&wait);

scanf() is just like printf() in that it requires a format string. Your code will compile because &wait is the right type, but anything could happen because &wait does not point to a string. The whole thing should look like this:

/* unnamed block so wait can be declared */
{
    char wait;

    printf("Enter to exit");

    /* flush the stream if you do not print '\n' */
    fflush(stdout);
    scanf("%c", &wait);
}

But in both your C and C++ code, that whole wait thing is more verbose than it needs to be. In C++ you can do cin.get(); and in C you can do getchar(); for the same effect as a char variable and operator>> or scanf().

Using the same style, I would write the code like this:

#include <stdio.h>

double factorial(int n);

int main()
{
    int i;

    printf("N          Factorial\n");
    printf("--------------------\n");

    for(i = 15; i > 0; --i)
    {
        printf("%-11d%.2f\n", i, factorial(i));
    }

    printf("Enter to exit");
    fflush(stdout);
    getchar();

    return 0;
}

double …
Grn Xtrm commented: Thanks for the help +1
Tom Gunn 1,164 Practically a Master Poster

What you could do is, since you are getting inputs, you can make sure that
the inputs are greater than the last input.

example run :

Please enter a number  :  3
Please enter a number greater than 3 :  5
Please enter a number greater than 5 : 23
Please enter a number greater than 23 :  -42
<Invalid choice> 
Please enter a number greater than 23 : 45
//and so on

But I don't know if this is allowed for you.

This is a great way to think outside the box, but I do not think it is a better solution because it delegates unnecessary work to the end user. I know I would be frustrated with software that did this to me, and I do not get frustrated easily. :D

Tom Gunn 1,164 Practically a Master Poster

if i want to find out a given tree is balanced or not how to find out based on height.

As long as you use the same definition of height when checking the balance, either function will tell you the same thing. You can recursively check that the subtrees of each node do not differ by more than one: abs(Height(root->left) - Height(root->right)) < 2 That gives you a balance quality along the lines of an AVL self-balancing tree.

Tom Gunn 1,164 Practically a Master Poster

CArray<> is an MFC class, right? The problem is almost surely going to be in your code, not the code of CArray<>. Can you post a small program that has the same error so that everyone can see how you are using the class?

Tom Gunn 1,164 Practically a Master Poster

I am adding an integer to a type largeInt, but I have not created an overloaded method that accepts largeInt and numerics as input, only one that inputs largeInts and strings. It compiles and runs fine without even a warning.

The largeInt class has an implicit constructor that takes a long type as the parameter. You typed cout << x + 2 << endl; , but what actually happens is cout << x + largeInt(2) << endl; .

Tom Gunn 1,164 Practically a Master Poster

An expression tree is a tree, not necessarily a binary tree, that holds the parts of an expression the same way a stack might hold them for prefix evaluation:

Expression:
2+(4*3)

Stack:
[+][2][*][4][3]

Expression Tree:
  +
 / \
2   *
   / \
  4   3

Look up how to convert infix notation to prefix notation and how to evaluate prefix notation using a stack. That is the first step toward understanding how expression trees work because they do the same thing.

Tom Gunn 1,164 Practically a Master Poster

the program continue showing lines from file even the file don't exist anymore.
My problem is that i don't understand why it still prints lines after file deletion.

I do not know how CentOS manages files in use, but it looks like the file is loaded into either memory or a temporary file to protect against exactly what you are trying to do. :) M$ Windows protects files in use by throwing up an error dialog box and not deleting the file.

Tom Gunn 1,164 Practically a Master Poster

if i have only one node in the list one function displays
height as -1 and other displays 0

Both are right. The function that returns -1 is probably treating an empty tree as an error case and returning a suitable code. The function that returns 0 is treating an empty tree as a non-error case and returning the actual height of 0 because there are no nodes.

if my tree is 40 and 20 with 40 as root node
then 1 displays 1 and other displays 2.

Both are right. The height of a BST has different technical definitions depending on who you ask. Sometimes the root is included in the count, sometimes it is not. The first function does not include the root in the height, and the second function does. Pick the one you think makes more sense and stick to it. My opinion is that the root should count if it has legit data. A dummy root should not count.

Tom Gunn 1,164 Practically a Master Poster

Move left up 1, move end down 1. If left == mid || right == mid then stop.

You can also do away with the middle variable because that case is identical to when left == right .

Tom Gunn 1,164 Practically a Master Poster

Technically all you need is a stack to store the nodes needed to get back to the nearest root and traverse the other subtree. So the memory cost is O(logN), not O(N), because the size of the stack has at most as many nodes as height(tree) .

The only way I can think of to traverse without using extra storage is destructive and less efficient. Let us say you want to do an in order traversal. Start with the root and whenever the left node is not a null pointer, rotate right. When the left node is a null pointer, visit the node and move to the right, then keep doing the same thing until the node is a null pointer:

while (node)
{
    if (node->left) node = RotateRight(node);
    else
    {
        visit(node);
        node = node->right;
    }
}

This algorithm is less efficient because of the rotations, and it is destructive because the structure of the tree changes after the traversal into the worst case of a BST. However, the good news is that this is also the first step of a perfect balancing algorithm called DSW. If you want, after the traversal you can add the second step and get a better tree than you probably started with. :)

Another good use for this traversal is destroying the tree and freeing nodes. Because the nodes are all being destroyed anyway, the structure does not matter anymore.

Tom Gunn 1,164 Practically a Master Poster

What is the error and what line is it reported on?

Tom Gunn 1,164 Practically a Master Poster

Grab the whole line, then parse it. You can parse with string streams using the same syntax as cin:

string line;

getline(cin, line);

istringstream iss(line);
int value;

while (iss >> value) cout << value << '\n';
Tom Gunn 1,164 Practically a Master Poster

can you show me the codes? ^^

No. This is a simple homework problem, and Daniweb's homework policy is not to give code examples without proof of effort.

Tom Gunn 1,164 Practically a Master Poster

Start by making a subset of the pattern:

*0000000*
0*00000*0
00*000*00
000*0*000

This is easier to visualize with two counters to mark the stars. After you get this one, you can add the central star that does not ever move.

Tom Gunn 1,164 Practically a Master Poster

Do we need to make any changes in the structure of tree , i mean any extra pointers in the structure declaration to hold the parent address when going down the tree.

Having parent pointers can help make the code simpler, and you do not need to worry about managing a separate stack. But parent pointers also take up space in each node and might not be practical all of the time.

i am confused with the definitions itself.

Height and depth. So the depth refers to a single node and the height refers to the entire tree.

Tom Gunn 1,164 Practically a Master Poster

Compilers usually have macros for versioning. You can use those to figure out which compiler is doing the compiling:

#if !defined(_MSC_VER)
#error Microsoft Visual Studio is required
#endif
Tom Gunn 1,164 Practically a Master Poster

I understand both of those facts but I thought that here, I'm only accessing the private members via the friend class, which I thought would be okay.

Making a friend to a class does not make the private members public. FriendClass can access UnrelatedClass' private members, but those private members are still private. Users of FriendClass cannot access them any more than non-friends of UnrelatedClass can.

Is there any ugly hack I can use to get around this?

There are a few, and none of them are recommended. But since you asked for an ugly hack, I will show you one. Use it at your own risk:

void DerivedClass::Foo()
{
    *reinterpret_cast<float*>(m_hUnrelatedClass) = 2.0;
}

This hack assumes that CHandle<> is a smart pointer. Do whatever you need to do to get the address of the UnrelatedClass object pointed to by the field.

It works like this: UnrelatedClass has no virtual members, which means the object structure is easier to predict with some accuracy. There is only one field and it is the field you want, so you can assume that for an object of UnrelatedClass, &obj.fNumber is the same address as &obj. If that is true and you cast that address to float*, you can access fNumber even though it is private.

Tom Gunn 1,164 Practically a Master Poster

return *nodePtr->data;

Unless data is a pointer to a pointer, this either returns data or throws an indirection error. To get the address of an object you use the & operator:

return &nodePtr->data;
mrnutty commented: Always get there before others, huh? +4
Tom Gunn 1,164 Practically a Master Poster

Yea, but if you write it like this: if(1 = a) your compiler will report it as an error, saving you much headache :P

But when you write it like this: if (a = b) your compiler might not make a peep. I do not use this idiom because it only applies when one of the operands is a constant. If you can remember to swap the operands when one is a constant but take care to use == when both are variable, you can remember to use lint and not worry about it. :D

Tom Gunn 1,164 Practically a Master Poster

be warned its over 1600 lines of code

The problem is as we said at first. You are using things before they are declared. The cls() function is one example. You use it in the definition of the Pet class, but it is declared after the Pet class definition. Think of the declare before use rule as being top-down. If you flatten out your code into one file, the declaration has to be above the first use.

Tom Gunn 1,164 Practically a Master Poster

This is an example of how to turn numbers into words. 1473 would get translated to "one thousand four hundred seventy three", for example. The class has a simple interface and can handle any value representable by unsigned int. The implementation recursively processes groups of 3 digits using table lookups for the word strings.

Note to cheaters: The code was written so that a teacher can tell if you try to steal it and turn it in for a homework grade.

tux4life commented: Incredibly nice! +21
Nick Evan commented: That's just awesome. Took a while to figure out ;) +31
amrith92 commented: Must've taken some thought!! I like it :) +2
Tom Gunn 1,164 Practically a Master Poster

You guys make it sound so easy...........

It only sounds easy because we have learned by making the same mistakes before. I still mistype counters all the time, so I know how to find it and prevent it. ;)

Tom Gunn 1,164 Practically a Master Poster
for (int j = 1; j <= (2 * i - 1); i++)

Your bug is the reason why I do not use i and j for counters. ;) They look so much alike it is easy to mistype and not be able to see it. In the code above you increment i instead of j. x and y are easier to tell apart. Compare this with your code and put the bug back in to see if it is easier to find with different counter names:

void drawShape(int nrR, char a, char b)
{
    for (int x = 1; x <= nrR; x++)
    {
        for (int y = 1; y <= (nrR - x + 1) ; y++) cout << b;
        for (int y = 1; y <= (2 * x - 1); y++) cout << a;
        for (int y = 1; y <= (nrR - x + 1) ; y++) cout << b;
        cout << endl;
    }

    // Bottom row
    for (int x = 1; x <= (2 * nrR + 1); x++) cout << b;
    cout << endl;
}
Tom Gunn 1,164 Practically a Master Poster

Dave Sinkula's idea is good, but I think it is easier to see what goes on by printing the intermediate results too, but in binary instead of hex:

#include <iostream>
#include <limits>
#include <bitset>

int main()
{
    using namespace std;

    //int tmp = 0xff000000 | ((int)(val) << 16 | (int)(val ) << 8 | (int)(val));

    // breaking the expression down into component parts
    unsigned char val = 0xA5;
    unsigned tmp = 0xff000000;
    unsigned shift1 = (unsigned)(val);
    unsigned shift2 = (unsigned)(val) << 8;
    unsigned shift3 = (unsigned)(val) << 16;
    unsigned paste1 = (shift3 | shift2 | shift1);
    unsigned paste2 = tmp | paste1;

    cout << bitset<numeric_limits<unsigned>::digits>(tmp) << '\n'
         << bitset<numeric_limits<unsigned>::digits>(shift1) << '\n'
         << bitset<numeric_limits<unsigned>::digits>(shift2) << '\n'
         << bitset<numeric_limits<unsigned>::digits>(shift3) << '\n'
         << bitset<numeric_limits<unsigned>::digits>(paste1) << '\n'
         << bitset<numeric_limits<unsigned>::digits>(paste2) << '\n';
}
Dave Sinkula commented: Danke. +28
Tom Gunn 1,164 Practically a Master Poster

Where is the 'All of the above' option?

Tom Gunn 1,164 Practically a Master Poster

Yeah yeah, that's all fine, but I personally like learning from someone who is better then me

I do that too. The more people you learn from, the better you will be. :)

Tom Gunn 1,164 Practically a Master Poster

You can call a function provided it has already been declared:

void afunction();

class example {
    public:
    example();
    ~example();
    
    void doSomthing() {
        afunction();
    }
};

void afunction() {
    //do more things
}

A definition is also a declaration, so you can move the definition above your class definition for the same effect:

void afunction() {
    //do more things
}

class example {
    public:
    example();
    ~example();
    
    void doSomthing() {
        afunction();
    }
};

Note the semicolon at the end of the class definition that I added. That is important, and forgetting it usually causes incomprehensible errors. ;)

Tom Gunn 1,164 Practically a Master Poster

Seems a good text, but I wonder about the choice of using main() as opposed to int main() ?

C++ evolved from C89, and C89 supports a feature called implicit int. If the type is not explicitly stated, int is assumed. These two definitions were the same in C89:

main()
{
    return 0;
}
int main()
{
    return 0;
}

C99 and standard C++ removed that feature, so newer compilers are starting to disallow it completely.

Whats the deal? Why would the author recommend that?

C++ went for a long time before it was standardized. A lot of compilers and books were written before implicit int was removed. Your book was probably written before 1998. That is the risk of using newer compilers with code from older books, but it helps you learn to manage legacy code. :D

Tom Gunn 1,164 Practically a Master Poster

One problem is that you never actually insert the node in that method. :) Another thing I noticed is that you do not handle edge cases. What happens if you call InsertAfter() on an empty list or the search fails? Inserting to an empty list can be a special case, and then you do not need to check currNode for NULL in the loop. If the node is not in the list, you can check currNode->next for NULL and use that to stop the loop. That way the next insertion will be at the end.

The last problem is that your algorithm is too complex. A previous node pointer is appropriate for an insert before operation, but with insert after you only need the current pointer:

if (IsEmpty())
{
    // special case: insert to empty list
    newNode->next = NULL;
    head = newNode;
}
else
{
    Node* currNode = head;

    while (currNode->next && currNode->data != x) 
    {
        currNode = currNode->next;
    }

    newNode->next = currNode->next;
    currNode->next = newNode;
}

It helps to draw the structure of the list as you fiddle with it. Visualizing data structures makes them easier to write code for. :)

Tom Gunn 1,164 Practically a Master Poster

Why on earth would you need C++ lessons from someone with (only) 2 years of experience? :icon_eek:

Egos get in the way of progress. ;) I have learned from less experienced programmers before, and it taught me that I can learn to be a better programmer from anybody, regardless of experience.

Tom Gunn 1,164 Practically a Master Poster

Unless the lines are formatted to have exactly the same length, getline() is really the best way to do what you want, even if you throw away most of the lines:

for (int x = 0; getline(fs, line) && x < selectedLine; ++x)
{
    // all work in condition
}

if (!fs)
{
    cerr << "could not load requested line\n";
}
Tom Gunn 1,164 Practically a Master Poster

but what if I want the hexadecimal 199 to be displayed in binary?

printf() does not have a conversion to binary. The C++ library has a bitset<> class that will indirectly do it for you, but you need to use cout to print directly, or manually convert to a string for printf():

#include <iostream>
#include <limits>
#include <bitset>

int main()
{
    std::cout << std::bitset<std::numeric_limits<int>::digits>(0x199) << '\n';
}

The other alternative is manually converting the number to a binary string. If you search this forum you can find tons of threads about how to do it that way.

kvprajapati commented: I appreciate your knowledge. +13
tux4life commented: Great post, keep up the good work Tommy ! :) +21
Tom Gunn 1,164 Practically a Master Poster
printf("name=%s",b1.name);
printf("\nname=%s",&b1.name);

Technically the second statement is undefined behavior because the %s modifier expects a char pointer, but you pass a pointer to a char pointer. The types do not match. In reality it will probably work because b1.name and &b1.name should both evaluate to the same address even if the types are different. printf() will get the address and cast it to the expected type, so both printf() calls print a char pointer using the same address.

But it is not guaranteed to work, so you should not use the second printf() statement.

Tom Gunn 1,164 Practically a Master Poster

I think it is better to learn more about C++ than the basics first. You can learn about writing game logic without adding the complexity of graphics to your program. If you start learning how to make graphics with incomplete knowledge of C++, you will end up struggling with the language and the graphics API at the same time. That makes learning harder.

Tom Gunn 1,164 Practically a Master Poster

The forum is buzzing with questions about tokenizing a C++ string. This is a short function that does it and returns a vector of the tokens. As an option, the delimiter string can represent either a multichar delimiter or a collection of single char delimiters:

// multichar delimiter == "^^"

"aa^^bb^c^^d"

becomes

"aa"
"bb^c"
"d"
// single char delimiter list == "^,"

"aa^^b,b^c^^d"

becomes

"aa"
""
"b"
"b"
"c"
""
"d"

A test driver is not included because that confused people with my last snippet.