??? 02/23/08 22:30 Modified: 02/23/08 23:11 Read: times Msg Score: +1 +1 Good Question |
#151357 - Putting it all together Responding to: ???'s previous message |
There are some subtle aspects of how C handles strings that everyone is dancing around here but nobody is explaining very clearly because it's a lot of work. Let me try to fill in the gaps.
Hint #1. When you code a literal string in C, it automatically adds a byte containing zero at the end to mark the end of the string. So, when you code: char string[] = "abcde";that makes an array of six bytes (not five). The first five, string[0] through string[4], contain the characters 'a' through 'e', as you'd expect. The sixth byte, string[5], contains the character '\0', or simply zero. Hint #2. When you concatenate literal strings in your program, the compiler lumps them all together into one string with a single '\0' at the end. So, when you code: unsigned char code phrases[] = { "ABC" "DEF......." "XYZ......." };this is exactly as if you'd written unsigned char code phrases[] = "ABCDEF.......XYZ.......";That gives you a single array of 24 bytes with a single '\0' at the end. As you have discovered, in order to recover what you originally thought of as three separate strings, you have to pad the strings so they are all the same length, and then you have to do some goofy address calcualtions yourself, like this: x + line_no * MAXCHARS_ON_LINEThis is not what you want, because your strings are not all the same length, and you shouldn't have to explicitly code the low-level address calcualtions. Tsuneo hinted at a better solution, which I will expand here as ... Hint #3. You should code your string table like this: unsigned char code *phrases[] = { "Short", "Medium", "Very long" };This may be confusing because it looks so much like the previous example, but it's really quite different. By coding "*phrases[]" instead of just "phrases[]" (without the *), you're telling the compiler you want an <array of pointers to char> instead of an <array of char>. Then, by separating the three strings with commas, you instruct the compiler to make three separate strings, each with its own terminating zero, instead of just one. So two things happen here. First the compiler makes three character arrays, one for each of the three strings that you specified. The first is six bytes long and contains the characters S-h-o-r-t plus the terminating zero. The second is seven bytes long and contains the characters M-e-d-i-u-m plus a terminating zero. The third is ten bytes long and contains V-e-r-y- -l-o-n-g plus the terminating zero. The compiler puts these characters into memory wherever it feels like. Most of the time, you don't know or care exactly where. Then the compiler also makes the phrases[] array and initializes it with pointers to the three strings. That means the phrases[] array contains three elements. The first, phrases[0], contains a pointer to the beginning of the first string. The second, phrases[1], contains a pointer to the beginning of the second string. The third, phrases[2], contains a pointer to the beginning of the third string. As Michael pointed out, you can #define a symbol that represents the number of strings by coding something like #define NUMBER_OF_STRINGS (sizeof(phrases) / sizeof(char *))Now, with all that set up, you can see that the easy way to iterate through the strings is to create a for loop that iterates from 0 up to (but not including) NUMBER_OF_STRINGS. And the easy way to iterate through the characters within any one of the strings is to start at the beginning of the string and check for the terminating zero at each step. So a bit of top-down pseudocode for your program would look like this: START main() REPEAT FOR each string from 0 to NUMBER_OF_STRINGS-1 CALL Clear Display CALL Put Phrase(current string) CALL Word Delay ENDFOR FOREVER START Put Phrase Start at first character in phrase WHILE Not yet at terminating zero CALL Put Character(current character) Advance to next character ENDWHILE END START Put Character Copy character to P0 CALL Write Enable ENDHint #4.When you're experimenting with things like we're discussing here, you may be better off working on your PC than on your embedded system. The debugging tools will probably be better on the PC, the edit-compile-debug cycle will be shorter, printf() will work, etc., etc. Hope this helps. -- Russ |