char represents a single character. A string is a bunch of these stored together somewhere in memory, with a NUL terminating character so we can detect where that string finishes. So, when we have a memory location storing a bunch of values of some type, we use a pointer. It holds a memory address that "points" at the start. The type for a string is char*.
To illustrate, let's draw out some bytes in memory showing a string at some address, let's imagine we have a 32-bit computer and for argument's sake the string begins at the address 0xffa01000:
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
0xffa01000 | R | o | c | k | ~ | ? | ? | ? |
+---+---+---+---+---+---+---+---+
The above is what "Rock" looks like in memory. Each one of those cells is one byte holding a char value. Note that I've used ~ to represent the NUL byte and ? to represent memory we don't care about (because it's not part of the string).
If you want to store a value that points to that string, you use a pointer:
const char* rock = "Rock";
With our example from earlier, the pointer rock now holds the address 0xffa01000 and if we start reading information out of memory from there until we hit the NUL byte, then we will have read the string "Rock".
You can use a pointer like an array. From above, rock[0] will give you the character 'R', rock[1] will give 'o', and so on...
So there's some basics on what strings actually are in C. But back to your game.
With what you're trying to do, the goal is probably to use a value of 0, 1 or 2 to represent a weapon. Because it's just easier to work with. You can always turn that into a string when you need to. Here is an example of how you could do that:
const char* weaponName(int w)
{
static const char* names[] = {
"Rock",
"Paper",
"Scissors"
};
// Note: the defensive programming approach would also range-test this index
// before using it.
return names[w];
}
This function just uses the weapon number as an index to find a string in an array. Think back to earlier... What we have here is just an array of pointers to strings that live somewhere in memory. You don't need to care where.
Note that I've also used const. Don't worry too much about that, but what this does is prevents me from accidentally modifying those strings. Modifying string literals is not allowed, and so we store them as constants to make the compiler complain if we try to modify them.
As for static, well that's another topic but it basically means that one copy of this array will be always in memory, even after the function returns. So I don't need to be concerned about my strings somehow not existing after the function returns. They probably wouldn't disappear anyway, but this makes sure.
Anyway, back to how to use this, it's quite simple. Your random weapon roll becomes a one-line function, and getting the string representation is just a call to the function we made earlier.
Here's some code that will roll a weapon 10 times and print out what it got:
int randomWeapon()
{
return rand() % 3;
}
int main()
{
// Seed the random generator -- you should only do this once!
srand(time(0));
for (int i = 0; i < 10; ++i)
{
int weapon = randomWeapon();
printf("%s\n", weaponName(weapon));
}
}
char*.char, and then returning that value as an integer. With compiler warnings enabled, your compiler should be throwing a complete tantrum right now.strcpyandstrncpyin thestring.hheader.ifblocks. That makes a variable local to the block, it doesn't update the variable declared at the top of the function.intwhen you want to return the string?