String Arrays
trustworthy
Posts: 74
When parsing a lot of data and the strings (E.G. from a security system) are very similar, can you do this...
and then when parsing the buffer from the device...
Or do I really need to start using structures?
DEFINE_CONSTANT CHAR strZONE_ID [xxx] [9] = { '[C01:X01]', '[C01:X02]', '[C01:X03]' .... etc }
and then when parsing the buffer from the device...
.... { STACK_VAR CHAR BufferReply BufferReply = REMOVE_STRING ( DeviceBuffer, "13", 1 ) STACK_VAR INTEGER nZoneIndex nZoneIndex = GET_LAST (strZONE_ID) { SELECT { ACTIVE FIND_STRING ( BufferReply, strZONE_ID [ nZoneIndex ], 1 ) : { SEND_COMMAND dvTP_PORT_x, " '^TXT-', nZoneIndex, ',0, THIS ZONE IS IN ALARM, EVACUATE IMMEDIATELY!' " } } } } ...
Or do I really need to start using structures?
0
Comments
GET_LAST:
If you define an event (in this case a button event) you create an event table based on a button array (channel numbers) and a TP or array of TPs. So when this button event is triggered the get_last will only return the index of the TP used or button used. Even if you have a single TP I like to use a TP_array with a single TP in it just so I can use get_last. Also makes adding TPs to existing code alot easier.
In your code the use of get_last has no way of figuring out what you're asking since the array you're using isn't part of the event table.
What I'm trying to achieve is not coding 150-odd SELECT...ACTIVEs (in the DATA_EVENT for the device buffer) based on individual strings that are the same length but cant return me a unique integer (the string could also be something like B02:Z01, B01:Z15, C01:Z15 etc etc) to allow me to easily give some kind of feedback on a panel (i.e. a button relating to an arbitrary zone will flash when in alarm or tamper).
Maybe I could tie the string indexes to a channel event? I use G_L all the time for channel, button and level events and just thought it might be extended into something like this. A data_event is still an event after all.
PS
I just tried to code out a SWITCH...CASE but failed dismally x-$
Think I need to sleep on it.....
That's what a hash is for.
Paul
What's a hash?
:-)
If I understand what you are doing:
You are receiving a response from a device and you are placing that response in a string variable named BufferReply. You want to find the index number of the row in your string array (strZONE_ID) that matches the string in BufferReply and use that index number to identify the zone.
You can use a for loop to do this:
I think the above will do what you want, I don't see the need for the select:active.
"hash" is a word used by computer science professionals to demonstrate that they know more than engineers. I think that in the current case a "hash" would be an array of index numbers that would indicate how the strings in your array would map to the zones in the system. You are obviating the need for this by putting your string names in your array in zone order: i.e. the index numbers match the zone numbers. Of course, I'm an engineer and not a computer science professional so I can't be sure that this explanation of "hash" was what was intended.
Google "hash table" and you'll find better explanations.
Google would be the place to turn since the subject is so huge, but for instance you could sum all the characters in the incoming command to get a unique or almost unique integer that would tell you which command came in and respond accordingly. This saves the use of loops with text finding functions in them that are typically slow.
Paul
This way, instead of doing 150 select..actives for each message type, you do a switch..case based on the message type and handle it appropriately using the zone number you parsed out of the message.
A quick example:
Jeff
I think here you might want a 'break' in the for loop once the string has been found. No point in continuing to search once you have found what you are looking for.
Paul
True enough, though it won't save much time unless the array is very large and then you would probably want to do something other than search an array with a for loop.
or the code gets executed often. Not sure which security system the OP is using but the ones I end up working with constantly spew so much feedback that an efficient parsing routine is necessary. Calling find_string 150 times for every string that the security system returns would likely slow down panel feedback I would think. YMMV.
Paul
The For loop did occur to me last night but it was far too late for me to elaborate on it.
The format concept gives is something like "preamble, date, time, input ID that triggered the last string (in e.g. C01:Z08 format - which means Controller Module 01, Zone input 8 - the first letter can change according to the module it is and the second letter according to the TYPE of input (e.g. standard, auxiliary, others) ) and then On or Off, and when its in Alarm the "Alarm" comes BEFORE the ID. There are two modes of responses, the first is Full Text which says literally "East Corridor 14 Alarm" or "John Smith opened the Fire Exit Door 12 at such and such a time" which is actually difficult to parse because of such variance in string length, not to mention the client could easily change the name of Zones. The second is ID only, which is what I'm using and is a lot more consistent.
When the client confirms the order I will try these different methods out (I've obviously already got comms) and use a bit of trial and error to find the one which is most efficient.
Thanks everyone for the responses!
If you think about what the find_string command has to do to find a match it's a very laborious process. Short strings are obviously less laborious than long strings so when using find string it's best to use the shortest string possible that will return what you want.
If you can avoid putting find_string in a loop which it this case isn't even needed why do it.