Thread: Newbi Help Needed with comparing data

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    9

    Newbi Help Needed with comparing data

    Hi all.

    I am new to C, and am stuck on a project I am working on. It is actually for an Atmel AVR Micro controller.

    I am reading in Data from one RS232 port, then sending out a message on a 2nd RS232 port depending on the data coming in.

    The project is basically a data converter. I know a list of 30 possible messages that could come in on say Port 1, and 30 new messages I will send out on Port 2.

    Now I am reading the data in with a loop, and writing it to a variable called ReceiveData.

    So what I need to do is send out a new message depending on the message that comes in. Anything else will be ignored.

    It is actually an interface between to pieces of hardware.

    I am not sure the best way to look out for 30 different messages.

    Any pointers would be great.

    Cheers,
    Will

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by wcavanagh View Post
    I am not sure the best way to look out for 30 different messages.
    This depends completely on the nature of the messages. Are they all the same length? Are they strings?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    9
    Quote Originally Posted by MK27 View Post
    This depends completely on the nature of the messages. Are they all the same length? Are they strings?
    Doh, knew I forgot something, yes they are all strings it is serial data, they vary in length, but the message will always be the same.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Look up strcmp(), strncmp() and strstr(). If plausible, you can use strstr and/or strncmp to create a "tree" of possibilites, grouping messages with similar parts, eg. if there are messages "ALPHA17" and "ALPHA31", the top level check would be for ALPHA at the beginning, then for a suffix.

    Or you could just use a bunch of if/else with strcmp(). Be more specific, (like post the actual list of possible messages) and someone might have a clever idea.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    9
    Thank you for the reply, I did wonder about if / else, I have done a simular thing in VB in the past.

    Example IN Message.
    FF 33 EX 33 55 33 55 ACK

    Example OUT Message.
    44 55 44 55

    I have a protocol document for both devices, so would need to go through them to get them all, but you get the idea, I hope.

    Cheers,
    Will

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This may be too simple for you, but I'd consider an array of all thirty strings that are possible incoming messages, and a parallel array just like it, with the possible outgoing messages.

    So when the message at rxmsg[0][] is received, then the message at txmsg[0][] is sent out.

    That assumes that rxmsg[][] is a 2D array of char strings, as is txmsg, and that there is a one to one relationship between the messages.

    Additionally, I'd sort the rows in rxmsg, in ascending order, and then set up txmsg, correctly (don't sort those strings, of course).

    Now, with the sorted strings, you can use a faster binary search to find your matching string when you receive a message. Sounds like an extra step, but you need that index number, and it is just one fast search.

  7. #7
    Registered User
    Join Date
    Jan 2010
    Posts
    9
    That is a great idea. Did not even think of an array. I think you may have something there.

    Thanks soo, much

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Very welcome, and good luck.

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    9
    Ok guys, I have now created two 2D arrays. With colum 0 as index, values 1 - 30, these match up in both arrays and are sorted in order.

    Happy Days.

    Now I need to preform a search on array 1, column 1 for a sting e.g "55 44 98 22 44 33" find the index in column 0, then using that index look up column 1 in array 2 and get the string value, then I will output that value to the RS232 port.

    Now in VB I would create a loop to do this, but I really have no clue where to start with C.

    This is a learning curve, and im loving it. But any help would be fantastic.

    Cheers,
    Will

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    We'll use a loop, also. This is a loop called a "binary search". I just woke up (5:19 on the Wet Coast), so let me turn on the coffee maker and I'll post it up with an edit to this post.


    Just to be clear on something. Only the receive messages are sorted, right? The tx messages should NOT be sorted, but be in the same index number as the received message that they are correct for.

    We don't need an index number put into the string, unless each receive message can have more than one tx message that needs to go out.

    The index number we need will be FOUND implicitly, NOT explicitly. We have no need to list that correct index number, anywhere in the code.


    Back in a bit.

    Code:
    /* Using parallel arrays for one to one implicit indexing by Adak 
    
    status: ok
    
    */
    
    #include <stdio.h>
    #define ROW 10
    #define COL 20
    
    int binarySearch(char rx[ROW][COL], char *msg);
     
    int binarySearch(char rx[ROW][COL], char *msg) {
      int lo, mid, hi, num;
      lo = 0; 
      hi = ROW -1;
      
      while(lo <= hi) {
        mid = (lo + hi) / 2;
        num = strcmp(rx[mid], msg); 
        if(num > 0)
          hi = mid - 1;
        else if(num < 0)
          lo = mid + 1;
        else
          return mid; //msg was found, return the index to it
      }
      return 0;  //msg was not found
    
    }
    
    
    int main() {
       int i, r, c, found;
       char msg[COL + 1];
       char rx[ROW][COL] = {  //this is the array that is sorted
       {"00 00"},
       {"11 11"},
       {"22 22"},
       {"33 33"},
       {"44 44"},
       {"55 55"},
       {"66 66"},
       {"77 77"},
       {"88 88"},
       {"99 99"}
       };
       char tx[ROW][COL] = {   //this is implicitly linked to the rx array
       {"answer for zero"},
       {"answer for one"},
       {"answer for two"},
       {"answer for three"},
       {"answer for four"},
       {"answer for five"},
       {"answer for six"},
       {"answer for seven"},
       {"answer for eight"},
       {"answer for nine"}
       };
    
    
       do {
         printf("\n\n\n Enter your message [nn nn format, or q to quit]: ");
         for(i = 0; i <= COL; i++)
           msg[i] = '\0';
    
         fgets(msg, sizeof(msg), stdin);
         i = strlen(msg);
         while(i > -1)  {
           if(msg[i] == '\n')
             msg[i] = '\0';
           --i;
         }
         found = binarySearch(rx, msg);
         if (found) 
           printf("\nMessage was located: %s  Reply is: %s \n", rx[found], tx[found]);
         else if(msg[0] != 'q')
           printf("\nMessage %s was not found\n", msg);
       }while(msg[0] != 'q');
    
       printf("\n\n\t\t\t     press enter when ready");
       i = getchar();
       return 0;
    }
    With just a few dozen messages, a binary search is a bit of overkill, but it's a great tool to know. When the data gets thick as thieves, binary search really comes into it's own.
    Last edited by Adak; 01-24-2010 at 09:19 AM.

  11. #11
    Registered User
    Join Date
    Jan 2010
    Posts
    9
    Hi,

    Thank you again for your help, I can confirm that only the received messages are sorted in order. Eg.

    0 = 55 88 11 44
    1 = 44 22 88 55
    2 = 44 55 44 12

    and so on.

    Thanks again, I know the the importance of the coffee, I have been living on it writing this code. A steep learning curve, but I am finding the best way to learn is doing this project.

    Thanks
    Will

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is not sorted order:

    0 = 55 88 11 44
    1 = 44 22 88 55
    2 = 44 55 44 12

    This is sorted order:

    Index number = data
    ===============
    0 = 44 22 88 55
    1 = 44 55 44 12
    2 = 55 88 11 44

  13. #13
    Registered User
    Join Date
    Jan 2010
    Posts
    9
    Sorted. Array is now as you show mate.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    What did you think of the program I posted?

  15. #15
    Registered User
    Join Date
    Jan 2010
    Posts
    9
    oo just seen, thanks, having a look right now, over a fresh brew of coffee

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  2. Reading a file with Courier New characters
    By Noam in forum C Programming
    Replies: 3
    Last Post: 07-07-2006, 09:29 AM
  3. help with comparing data from a file
    By loso44x in forum C Programming
    Replies: 3
    Last Post: 10-03-2005, 01:57 PM
  4. Replies: 4
    Last Post: 06-14-2005, 05:45 AM
  5. can't insert data into my B-Tree class structure
    By daluu in forum C++ Programming
    Replies: 0
    Last Post: 12-05-2002, 06:03 PM