Let me try to see if I understand what TheStreet and his student are trying to do, and if I can help.
First, let's decide you can have up to 10 players, and each name can be up to 63 characters long. In C, you need to reserve one character for end-of-string mark, '\0'. Since you might decide to change the maximum number of players, let's make it a macro:
Next, we want to ask the names for all the players. I don't like to ask the number of players first, because it's simpler to just ask them each, and use some marker to indicate "no, that's all of us".Code:#include <stdio.h> #define MAX_PLAYERS 10 int main(void) { char name[MAX_PLAYERS][64]; int number[MAX_PLAYERS]; int players = 0; int player;
Let's use a while loop to ask for the name of each player. We need the limit on players, because we cannot go over the array bounds:
The scanf() function will return the number of conversions it did. It may be zero if there is no more input, or if the input does not match the pattern. Since we have 63 characters reserved for a player name, let's ask for any characters (but no more than 63) that are not newlines (CR or LF). The %63[^\r\n] is like %63s except that it accepts also spaces (it only stops at a newline). The original %s was unlimited, so typing a very long name would overrun the buffer (as sscanf() expects you to tell how long your buffers are; it does not check).Code:while (players < MAX_PLAYERS) { printf("Please input name for player %d, or - if no more players:\n", 1 + players);
If there was no name given, the above breaks out of the loop.Code:/* Scan for up to 63 characters not newlines (CR or LF) into name[players] */ if (scanf(" %63[^\r\n]", name[players]) < 1) break;
If the name is empty, or starts with a dash or underscore, we want to break out of the loop also:
At this point, we have a new players name in name[players]. Okay, so we have a new player. Increase the count, and ask for the next name, then:Code:/* No more names if empty name or starts with a - or a _ */ if (name[players][0] == '\0' || name[players][0] == '-' || name[players][0] == '_') break;
If there were no names given at all, we want to abort the program.Code:players++; }
Otherwise, we are ready to play the game.Code:if (players < 1) { printf("\nNo players at all? Okay, no game then.\n"); return 0; }
For this demonstration, lets just ask one number between 1 and 10 inclusive (with both 1 and 10 accepted) from each player, and storing it into number[player] for each one. This time, let's use a for loop:
It is very easy to input something that is really not a number, so we want to let the player retype their answer if that happens. One way to do that is to have a loop which asks until the answer is satisfactory. This one uses an endless while loop for that:Code:for (player = 0; player < players; player++) { printf("Your turn, %s. Please input a number between 1 and 10, inclusive.\n", name[player]);
Notice the less-than-one? If it is true, we did not get a number. scanf() does not discard the input, so we have to somehow "consume" it to discard it. The easiest is to ask scanf() to discard everything up to the next newline (by reading it, but not storing it anywhere):Code:while (1) { if (scanf(" %d", &number[player]) < 1) {
and then prompt the same player to retry.Code:/* Skip this line in the input buffer. */ scanf(" %*[^\r\n]");
Note that break breaks out of the loop, and continue skips to the next iteration of the current loop, starting at the start of the loop body. Both work only on the current loop, they don't affect the outer for loop in any way. Above, continue will therefore skip back to the scanf().Code:printf("That's not a number, %s. Try again.\n", name[player]); continue; }
Next, we check the number for validity:
At this point, we know the number is okay. So, we break out of the loop, so we can continue on in the for loop.Code:if (number[player] < 1) { printf("%d is too small; it must be between 1 and 10, inclusive. Try again, %s.\n", number[player], name[player]); continue; } else if (number[player] > 10) { printf("%d is too large; it must be between 1 and 10, inclusive. Try again, %s.\n", number[player], name[player]); continue; }
Note that the first brace above ended the while loop, and the second the for loop. The break only breaks out of the innermost scope, here out of the while loop, not all the way out of the for loop. Just out of the innermost while loop.Code:break; } }
At this point we know we have players players (0 to players-1), their names in name[] and chosen values in number[].
I don't know what you'd like to do with those numbers, so let's just output the choices and exit the program:
If you have any questions on any of the code above, please ask, and I'll try to explain.Code:printf("\nNumbers chosen:\n"); for (player = 0; player < players; player++) printf("%s: %d\n", name[player], number[player]); return 0; }