I have built a very small program that is a command line utility for generating alphanumeric characters of a certain length (up to a max. length) called randchars.
$ randchars 12
Prints twelve pseudo-random upper-/lower-case alphanumeric characters to stdout. The command line options -l and -u can be given, if somebody wishes to have only lower- or uppercase alphanumeric characters.
Here is the code, this is my first project while reading K&R. I know that in C99 I do not need to declare the variables on top of the functions, but I somehow grew to like it this way^^
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAX_CHARS 32
int is_lowercase(char c);
int is_uppercase(char c);
int is_digit(char c);
enum OPTS {
MIXED, // default
UPPERCASE, // -u
LOWERCASE, // -l
};
int main(int argc, char *argv[])
{
unsigned i, size, char_ok;
srand(time(0));
char chars[MAX_CHARS + 1];
char rchar, c;
enum OPTS mode;
// get options
if (argc < 2 || 3 < argc)
goto error_argc;
// size is last arg
size = atoi(argv[argc - 1]);
if (size == 0)
goto usage;
if (size > MAX_CHARS)
goto error_size;
mode = MIXED;
if (argc == 3) {
if (strcmp(argv[1], "-l") == 0)
mode = LOWERCASE;
else if (strcmp(argv[1], "-u") == 0)
mode = UPPERCASE;
else
goto error_opt;
}
// do actual computation of random chars
for (i = 0; i < size; i++) {
do {
c = rand() % ('z' + 1);
chars[i] = c;
switch(mode) {
case MIXED:
char_ok = is_digit(c) || is_uppercase(c) || is_lowercase(c);
break;
case LOWERCASE:
char_ok = is_digit(c) || is_lowercase(c);
break;
case UPPERCASE:
char_ok = is_digit(c) || is_uppercase(c);
break;
}
} while (!char_ok); // repeat if char is not ok
}
chars[size] = '\0';
printf("%s\n", chars);
return 0;
error_size:
printf("error: maximum sequence length: %u\n", MAX_CHARS);
goto usage;
error_opt:
printf("error: invalid option: %s\n", argv[1]);
goto usage;
error_argc:
printf("error: invalid amount of arguments: %u\n", argc);
goto usage;
usage:
printf("usage:\n\t%s [ -u | -l ] <n>\n", argv[0]);
return 1;
}
int is_lowercase(char c)
{
if ('a' <= c && c <='z')
return 1;
else
return 0;
}
int is_uppercase(char c)
{
if ('A' <= c && c <='Z')
return 1;
else
return 0;
}
int is_digit(char c)
{
if ('0' <= c && c <='9')
return 1;
else
return 0;
}