| ??? 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
END
Hint #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 |



