# Thread: very simple code to match letters to numbers

1. ## very simple code to match letters to numbers

Hi guys,

I'm a complete beginner to C. I have been reading quite a bit about it but not yet got stuck in, so I want to start right now.

I want to write a program that assigns a word to each number from say 1-100.

What's the best way to do this? I know that I could have an array for each of those values, but I can't put a string in an array right?

Do I need to combine pointers and arrays here?

You don't have to post, the code - even a word of guidance in the right direction would be much appreciated.

Thanks in advance of any replies posted,
Kop442000.

PS - assigning each word to a number, I want the program to generate a number randomly from this range (think I am ok with that), and then the user has to try and match the word. They are then told if they are successful or not. I guess how I do that part would depend on how you guys advise me to achieve the first part.

2. Originally Posted by kop442000
but I can't put a string in an array right?
You can't do anything with a string except put it in an array.
Code:
```char string[]="this is a string";
int i, len = strlen(string);
for (i=0;i<len;i++) printf("%c",string[i]);```
See the array?

So what you are talking about is actually a "two dimensional" array, that is, an array of arrays.

Code:
```	char rayofrays[3][16]={ "string one", "next string", "third string" };
int i;
for (i=0; i<3; i++) printf("%s\n", rayofrays[i]);```
Does that make sense?

3. ok got it.

That's great thanks for the help!

4. Ok so I have finished my code... I changed my mind with it a little bit.

It works as I want it to, I just wondered if you guys could tell me how you would have done it differently or more efficiently so that I can know for next time.

That would be very helpful, thank you:

int main()
{
srand(time(NULL));
char element[][15]={ "Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Fluorine",
"Neon", "Sodium", "Magnesium", "Aluminium", "Silicon", "Phosphorus", "Sulfur", "Chlorine", "Argon", "Potassium", "Calcium",
"Scandium", "Titanium", "Vanadium", "Chromium", "Manganese", "Iron", "Cobalt", "Nickel", "Copper", "Zinc", "Gallium", "Germanium",
"Arsenic", "Selenium", "Bromine", "Krypton", "Rubidium", "Strontium", "Yttrium", "Zirconium", "Niobium", "Molybdenum", "Technetium",
"Ruthenium", "Rhodium", "Palladium", "Silver", "Cadmium", "Indium", "Tin", "Antimony", "Tellurium", "Iodine", "Xenon", "Cesium",
"Barium", "Lanthanum", "Cerium", "Praseodymium", "Neodymium", "Promethium", "Samarium", "Europium", "Gadolinium", "Terbium",
"Dysprosium", "Holmium", "Erbium", "Thulium", "Ytterbium", "Lutetium", "Hafnium", "Tantalum", "Tungsten", "Rhenium", "Osmium",
"Actinium", "Thorium", "Protactinium", "Uranium"};
int r = rand() % 92;

printf("Enter the element with Atomic Number %d\n\n", r+1);

if (diff == 0)
printf("\nCorrect!\n");
else printf("\nIncorrect. The answer was %s.\n", element[r]);

}

5. Originally Posted by kop442000
Ok so I have finished my code... I changed my mind with it a little bit.

It works as I want it to, I just wondered if you guys could tell me how you would have done it differently or more efficiently so that I can know for next time.

That would be very helpful, thank you:

Code:
```int main()
{
srand(time(NULL));
char element[][15]={ "Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Fluorine",
"Neon", "Sodium", "Magnesium", "Aluminium", "Silicon", "Phosphorus", "Sulfur", "Chlorine", "Argon", "Potassium", "Calcium",
"Scandium", "Titanium", "Vanadium", "Chromium", "Manganese", "Iron", "Cobalt", "Nickel", "Copper", "Zinc", "Gallium", "Germanium",
"Arsenic", "Selenium", "Bromine", "Krypton", "Rubidium", "Strontium", "Yttrium", "Zirconium", "Niobium", "Molybdenum", "Technetium",
"Ruthenium", "Rhodium", "Palladium", "Silver", "Cadmium", "Indium", "Tin", "Antimony", "Tellurium", "Iodine", "Xenon", "Cesium",
"Barium", "Lanthanum", "Cerium", "Praseodymium", "Neodymium", "Promethium", "Samarium", "Europium", "Gadolinium", "Terbium",
"Dysprosium", "Holmium", "Erbium", "Thulium", "Ytterbium", "Lutetium", "Hafnium", "Tantalum", "Tungsten", "Rhenium", "Osmium",
"Actinium", "Thorium", "Protactinium", "Uranium"};
int r = rand() % 92;

printf("Enter the element with Atomic Number %d\n\n", r+1);

if (diff == 0)
printf("\nCorrect!\n");
else printf("\nIncorrect. The answer was %s.\n", element[r]);

}```
Although it's technically always correct to put double quotes around every string, when the string is being *first* initialized, many compilers allow a simpler format:

Code:
`char elements[][15] = "Hydrogen, Helium, Lithium";`
Edit:
I just tried this out, and my compilers all required at least a double quote mark at the end of each word. So ignore this suggestion.

You may want to give your compiler a try and see how it does.

For the scanf() for answer, remember that answer already *is* a pointer to the base of the answer array. So no & (ampersand), is needed, in the call to scanf().

int main() is good, but should have a return of 0 (or some integer value).

Case insensitive means changing all the letters to one case (whichever you like). tolower() and toupper(), could be used, but since you're learning, let's get a little trick in here:

Go to ascii tables and d/l the table. Now check out how the capital letters A-Z are all in sequence, one after the other. Note that the lowercase letters are arranged the same way - no gaps between letters.

Which means that there's a constant value between any two case letters: A-a, M-m, R-r, whatever. Get that number.

Say I want all the letters in a word made into uppercase, using this trick:
Any letter *minus* that constant number we just mentioned (if the letter is greater than or equal to 'a'), and poof! It's now an uppercase and matching, letter. a - constant = A.

Any letter *plus* that constant number we just mentioned (if the letter is less than or equal to 'Z'), and poof!. It's now a lowercase and matching, letter. A + constant = a

On the whole, use tolower() and toupper(), but it's a good trick to know.

Please put your program inside code tags - by highlighting the program, and then clicking on the # sign. If you'll keep the width limited to about 60 char's, it will allow this forum to display it neatly, without "busting" the page widths, and becoming much harder to read.

6. Thanks man, that was very helpful!

Will make the changes and post again.

Although it's technically always correct to put double quotes around every string, when the string is being *first* initialized, many compilers allow a simpler format:

Code:
`char elements[][15] = "Hydrogen, Helium, Lithium";`
You may want to give your compiler a try and see how it does.
And with that, how would the compiler tell whether you mean {"Hydrogen", "Helium", "Lithium"} or a single string "Hydrogen, Helium, Lithium"?

8. It can't, and I've edited the orginal post, to reflect that - thank you.

9. I would do this:
Code:
`char *elements[] = { "Hydrogen", "Helium", "Lithium" };`
That way you needn't worry about whether you've allowed sufficient width in your array for even the longest word, nor will you be wasting memory for all words that are less than that maximum. The compiler allocates just enough memory bytes for each word, albeit a pointer to each, plus terminating null.

None of your other comparison code needs to change.

10. If you declare it that way, then it should be:
Code:
`const char *elements[] = { "Hydrogen", "Helium", "Lithium" };`

11. I never use const. But if you don't trust yourself, then yeah.

12. Originally Posted by nonoob
I never use const. But if you don't trust yourself, then yeah.
It's not really a matter of trust, it's a matter of safety. String literals are often stored in read-only memory. If you try to write to that memory, your application will crash. Declaring them as const will at least give your compiler a chance to warn you if attempt to pass one of those pointers to a function that modifies the data.

13. That's not the way I understood the use of const. The fact that the const is optional indicates to me that you may want to modify such an initialized array - being careful of course that you never write more bytes than were allocated.

If an initialized array was always meant to be const, then the compiler would enforce strict checking all the time. And again, you wouldn't need to include const because it would be redundant.

14. Like I said, string literals are not optional, they should always be const. The following code causes a segmentation fault using GCC on Linux:

Code:
```#include <string.h>

int main(void)
{
char* s = "this string is read-only";
memset(s, 0, strlen(s));
return 0;
}```
There is no buffer over-run, the error is that you are attempting to write to memory that is read-only.

15. Originally Posted by nonoob
That's not the way I understood the use of const. The fact that the const is optional indicates to me that you may want to modify such an initialized array - being careful of course that you never write more bytes than were allocated.

If an initialized array was always meant to be const, then the compiler would enforce strict checking all the time. And again, you wouldn't need to include const because it would be redundant.
For this type of array, yes:
Code:
`char str[] = "abcd123";`
Because it creates an array on the stack big enough to initialize to the size of the string you're assigning, so you can write to it; but for this type of array:
Code:
`char* str = "abcd123";`
it's not a stack based array, it's a pointer to a read-only section of memory which contains the string literal "abcd123". So you should make it const.

Ideally, the compiler should (but doesn't) give you a warning or error if you don't make it const, but I didn't design the C standard, so I guess that one slipped past them.