Showing posts with label c. Show all posts
Showing posts with label c. Show all posts

Creating a templated Binary Search Tree Class in C

Creating a basic template Tree Class in C++
(Works in Linux and Windows)

If you just want the code and not the walkthrough, it is attached at the end (I use the GNU GPL license, so do whatever you want with the code as long as you mention me).

There a multiple benefits of creating a Tree class based on a template. With a template, the tree can be a container for anything while still being fairly clean code. We will also create this class to be easily inherited for other trees such as an AVL and Huffman tree (which we will implement later).

A tree is a widely used data structure which organizes a set of nodes containing data. More can be found on it here: http://en.wikipedia.org/wiki/Tree_%28data_structure%29

This tree will be a Binary Search Tree; however, it will be easily inheritable so that other trees (Binary trees, such as AVL and Red-Black) can be defined based on it.

First we will set up our Node as a holder for the data and tree information such as the parent and connected nodes (the leaves). I overload the < operator so that we can search and sort this tree using the c++ algorithm include if we so desire.

template <class T>
class Node {
public:
    T data;
    Node *left, *right, *parent;

    Node() {
        left = right = parent = NULL;
    };
    Node(T &value) {
        data = value;
    };
    ~Node() {
    };   
    void operator= (const Node<T> &other) {
        data = other.data;
    };
    bool operator< (T &other) {
        return (data < other);
    };
};

Our tree will basically just be a bunch of these Nodes pointing to each other, with some functions to manage the data structure.

template <class T>
class Tree {
public:
    Tree() {
        root = NULL;
    };

    ~Tree() {
        m_destroy(root);
    };

    //We will define these all as virtuals for inherited trees (like a Huffman Tree and AVL Tree shown later)
    virtual void insert(T &value) {
        m_insert(root,NULL,value);
    };
    virtual Node<T>* search(T &value) {
        return m_search(root,value);
    };
    virtual bool remove(T &value) {
        return m_remove(root,value);
    };
    virtual bool operator< (Tree<T> &other) {
        return (root->data < other.first()->data);
    };
    void operator= (Tree<T> &other) {
        m_equal(root,other.first());
    };
    Node<T>*& first() {
        return root;
    };


protected:
    //this will be our root node and private functions
    Node<T> *root;
    void m_equal(Node<T>*& node, Node<T>* value) {
        if(value != NULL) {
            node = new Node<T>();
            *node = *value;
            if(value->left != NULL)
                m_equal(node->left, value->left);
            if(value->right != NULL)
                m_equal(node->right, value->right);
        }
    }

    void m_destroy(Node<T>* value) {
        if(value != NULL) {
            m_destroy(value->left);
            m_destroy(value->right);
            delete value;
        }
    };
    void m_insert(Node<T> *&node, Node<T> *parent, T &value) {
        if(node == NULL) {
            node = new Node<T>();
            *node = value;
            node->parent = parent;
        } else if(value < node->data) {
            m_insert(node->left,node,value);
        } else
            m_insert(node->right,node,value);
    };
    void m_insert(Node<T> *&node, Node<T> *parent, Tree<T> &tree) {
        Node<T> *value = tree.first();
        if(node == NULL) {
            node = new Node<T>();
            *node = *value;
            node->parent = parent;
        } else if(value->data < node->data) {
            m_insert(node->left,tree);
        } else
            m_insert(node->right,tree);
    };
    Node<T>* m_search(Node<T> *node, T &value) {
        if(node == NULL)
            return NULL;
        else if(value == node->data)
            return node;
        else if(value < node->data)
            return m_search(node->left,value);
        else
            return m_search(node->right,value);
    };

    bool m_remove(Node<T> *node, T &value) {
        //messy, need to speed this up later
        Node<T> *tmp = m_search(root,value);
        if(tmp == NULL)
            return false;
        Node<T> *parent = tmp->parent;
        //am i the left or right of the parent?
        bool iamleft = false;
        if(parent->left == tmp)
            iamleft = true;
        if(tmp->left != NULL && tmp->right != NULL) {
            if(parent->left == NULL || parent->right == NULL) {
                parent->left = tmp->left;
                parent->right = tmp->right;
            } else {
                if(iamleft)
                    parent->left = tmp->left;
                else
                    parent->right = tmp->left;
                T data = tmp->right->data;
                delete tmp;
                m_insert(root,NULL,data);
            }
        } else if(tmp->left != NULL) {
            if(iamleft)
                parent->left = tmp->left;
            else
                parent->right = tmp->left;
        } else if(tmp->right != NULL ) {
            if(iamleft)
                parent->left = tmp->right;
            else
                parent->right = tmp->right;
        } else {
            if(iamleft)
                parent->left = NULL;
            else
                parent->right = NULL;
        }
        return true;
    };
};

And thats all we need for a basic binary search tree. The full code is shown below

Tree.h 

Consider donating to further my tinkering.


Places you can find me
Read More..

Using the Google Voice C API

First of all, this obviously isnt an official Google API. I wrote it because I wanted one in C++ and couldnt find one that worked.

That being said, the code is on github here (in the TextCommand folder) and is available under GPLv3 for anyone to use.
I know this could (maybe even should) have its own github project but since I use it for my home automation projects, its included in the PiAUISuite. That being said, the current gvapi binary is also compiled for the Pi. So you will need to run make gvapi if you want to use it on any other linux machine.

To include the C++ code in your own project, you just need to include gvoice.h in your file and then you should be able to access the GoogleVoice class. An excellent example to look at is gvapi.cpp since it shows how to interact with it. You should need only to call Init and Login, then you should be able to do any of the Google voice functions.

If you only to use gtextcommand to send commands to your pi, see here. If you want to send or check SMS without having to include the source in your code/project, just use the gvapi program. It can get contacts, send, receive, and delete SMS. It also comes in with built in spoof protection (this is included in GoogleVoice::CheckSMS).

Heres a quick video demo as an example of the kinds of things you can do with gvapi


Using the gvapi program is fairly simple and its man page is below:


gvapi


gvapi - Use of Google voice API in order to send and receive SMS  

SYNOPSIS

gvapi [OPTIONS]...  

DESCRIPTION

gvapi was compiled for use with home automation on the Raspberry Pi but will work on any linux system with an internet connection. It uses curl and boost regex in order to login and stores the cookie in /dev/shm. It only logs in once every 24 hours to save time. It supports a multitude of different options and parameters. For help/comments/questions, feel free to e-mail me at help@stevenhickson.com. I answer sporadically but do eventually respond.
 

OPTIONS

-?
Same as -h
-c
Checks your incoming text messages to see if you have anything unread. It will mark it whatever it outputs as read unless you also use the -r flag. If you include a number with the -n flag, you can specify it to only check messages received from that number. You can also use the -k flag to specify that the message must start with a certain keyword.
-d
Sets debug mode on. You can also specify debug mode from 1 - 3, where 3 is the most verbose.
Ex: gvapi -c -d2
-h
Asks for some quick general use help for gvapi.
-i
Outputs the contacts of your google voice account in the form name==number
-k KEYWORD
Sets a keyword that has to be in the beginning of the text message for it to be returned. This is useful as a password for parsing only certain messages.
-m MESSAGE
Sends the message you specify. This should be in quotes if it contains special characters or a space. The number also has to be specified otherwise it wont have a message to send
Ex: gvapi -n +15551234 -m Hello
-n NUMBER
Can be used with the -c flag to check messages from a certain number or the -m flag to send a message. Can be in a format without the country code, with just the country code, or with a plus sign and the country code. If the formost, it interprets it as a US number.
Ex: gvapi -n 5551234 -c
-p PASSWORD
Can be used with the -u flag to log in manually. If not specified, the program uses the default username and password specified in ~/.gv
-r
Receives and deletes SMS messges. Can be used with the -c flag or without. It is the same as the -c flag but instead of just marking the messages as read. It deletes them.
-u USERNAME
Can be used with the -p flag to log in manually. See the -p flag for more details. Cannot be used without the -p flag.
-v
Outputs version and creater information

AUTHOR

Steven Hickson (help@stevenhickson.com)  

BUGS

No known bugs. To report bugs, send a clear description to help@stevenhickson.comSince this program is fairly crude, user typos could cause crashes/failed responses. Please read the man page thoroughly before submitting a bug.  

COPYRIGHT

Copyright © 2013 Steven Hickson. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it as long as you give credit to the author and include this license. There is NO WARRANTY, to the extent permitted by law.  

HISTORY

This is the second major version of this program  

SEE ALSO

http://stevenhickson.blogspot.com/

Consider donating to further my tinkering.


Places you can find me
Read More..

C PUZZLE


  • main(){

            int a=10,*j;
      void *k;
            j=k=&a;
      j++; 
            k++;
      printf("
%u %u ",j,k);
}
Answer:
            Compiler error: Cannot increment a void pointer
Explanation:
Void pointers are generic pointers and they can be used only when the type is not known and as an intermediate address storage type. No pointer arithmetic can be done on it and you cannot apply indirection operator (*) on void pointers.

  • Printf can be implemented by using  __________ list.

Answer:
            Variable length argument lists

  •  char *someFun(){

                  char *temp = “string constant";
                  return temp;
            }
            int main(){
                  puts(someFun());
            }
            Answer:
                  string constant
            Explanation:
      The program suffers no problem and gives the output correctly because the character constants are stored in code/data area and not allocated in stack, so this doesn’t lead to dangling pointers.

  • char *someFun1(){

                  char temp[ ] = “string";
                  return temp;
            }
            char *someFun2(){
                  char temp[ ] = {‘s’, ‘t’,’r’,’i’,’n’,’g’};
                  return temp;
            }
            int main(){
                  puts(someFun1());
                  puts(someFun2());
            }
            Answer:
            Garbage values.
            Explanation:
Both the functions suffer from the problem of dangling pointers. In someFun1() temp is a character array and so the space for it is allocated in heap and is initialized with character string “string”. This is created dynamically as the function is called, so is also deleted dynamically on exiting the function so the string data is not available in the calling function main() leading to print some garbage values. The function someFun2() also suffers from the same problem but the problem can be easily identified in this case.

  • Explain Internal linkage.

Internal linkage means that all declarations of the identifier within one source file refer to a single entity but declarations of the same identifier in other source files refer to different entities.

  • Can the formal parameter to a function be declared static?

No, because arguments are always passed on the stack to support recursion.

  • What is an lvalue?

Something that can appear on the left side of the "=" sign, it identifies a place where the result can be stored. For example, in the equation a=b+25, a is an lvalue.
In the equation b+25=a, b+25 cannot be used as an lvalue, because it does not identify a specific place. Hence the above assignment is illegal.

  • Every expression that is an lvalue, is also an rvalue. Is the reverse true?

No, lvalue denotes a place in the computers memory. An rvalue denotes a value, so it can only be used on the right hand side of an assignment.

  • What happens if indirection is performed on a NULL pointer?

On some machines the indirection accesses the memory location zero. On other machines indirection on a NULL pointer cause a fault that terminate the program. Hence the result is implementation dependent.

  • Is the statement legal? d=10-*d.

Illegal because it specifies that an integer quantity (10-*d) be stored in a pointer variable

  • What does the below indicate?

 int *func(void)
void indicates that there arent any arguments.
there is one argument of type void.
Answer: a

  • What are data type modifiers?

To extend the data handling power, C adds 4 modifiers which may only be applied to char and int. They are namely signed, unsigned, long and short. Although long may also be applied to double.

  • Interpret the meaning of the following.

“ab”,”a+b”
“w+t”
Answer:
"ab","a+b"->open a binary file for appending
"w+t" ->create a text file for reading and writing.

  • What is NULL in the context of files?

In using files, if any error occurs, a NULL pointer is returned.

What is Register storage class?
It concerns itself with storing data in the registers of the microprocessor and not in memory. The value of the variable doesnt have to be loaded freshly from memory every time. Its important to realize that this a request to the compiler and not a directive. The compiler may not be able to do it. Since the registers are normally of 16 bits long, we can use the register storage class for ints and chars.

  • What is an assertion statement?

They are actually macros. They test statements you pass to them and if the statement is false, they halt the program and inform you that the assertion failed. It is defined in the header file <assert.h>.

Parse int *(*(*(*abc)())[6])();
abc is a pointer to a function returning a pointer to array of pointer to functions returning pointer to integer.

Read More..