Function Pointer Demo simplified
It makes more sense to show the basic usage of fps
committer: Markus Bröker <mbroeker@largo.homelinux.org>
/**
* clplaner.c
* Copyright (C) 2008 Markus Broeker
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#define MAXLOOP 25
#define MAXLINE 80
#ifndef MAXTEAM
#define MAXTEAM 32
#endif
#define getrandom(max) (1+(int)((float)(max)*rand()/RAND_MAX))
void swap (int *v, int i, int j)
{
int temp;
if (i == j)
return;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
void cleanup (char **first, char **second)
{
int i;
i = 0;
while (first[i] != NULL)
free (first[i++]);
i = 0;
while (second[i] != NULL)
free (second[i++]);
}
unsigned int time_seed ()
{
time_t now = time (NULL);
unsigned char *p = (unsigned char *)&now;
unsigned int seed = 0;
size_t i;
for (i = 0; i < sizeof (now); i++)
seed = seed * (UCHAR_MAX + 2U) + p[i];
return seed;
}
int getTeams (FILE * f, char **first, int *first_idx, char **second, int *second_idx)
{
int i;
char buffer[MAXLINE + 1];
char *ptr;
i = 0;
while ((i < MAXTEAM) && fgets (buffer, MAXLINE, f) != NULL) {
if ((first[i] = malloc (MAXLINE + 1)) == NULL) {
perror ("malloc");
break;
}
if ((ptr = strchr (buffer, '\n')))
*ptr = '\0';
strncpy (first[i], buffer, MAXLINE);
first_idx[i] = i;
if (fgets (buffer, MAXLINE, f) == NULL) {
printf ("You need 2, 4, 6, ..., or %d teams in your file\n", 2 * MAXTEAM);
second[i] = first[i + 1] = NULL;
cleanup (first, second);
fclose (f);
exit (EXIT_FAILURE);
}
if ((second[i] = malloc (MAXLINE + 1)) == NULL) {
perror ("malloc");
break;
}
if ((ptr = strchr (buffer, '\n')))
*ptr = '\0';
strncpy (second[i], buffer, MAXLINE);
second_idx[i] = i;
i++;
}
first[i] = second[i] = NULL;
return i;
}
void shakeTeamIdx (int *first_idx, int *second_idx, int teams)
{
int i, j, k;
/*
* Who wins the Title?
*/
if (teams == 1)
return;
/*
* swap the index MAXLOOP times...
*/
for (i = 0; i < MAXLOOP; i++) {
for (j = 0; j < teams; j++) {
k = getrandom (teams - 1);
swap (second_idx, j, k);
k = getrandom (teams - 1);
swap (first_idx, j, k);
}
}
/*
* avoid group clashes
*/
for (i = 0; i < teams - 1; i++) {
if (first_idx[i] == second_idx[i])
swap (first_idx, i, i + 1);
}
if (first_idx[i] == second_idx[i])
swap (first_idx, i, i - 1);
}
int main (int argc, char **argv)
{
FILE *f;
char *first[MAXTEAM + 1];
char *second[MAXTEAM + 1];
int first_idx[MAXTEAM];
int second_idx[MAXTEAM];
int i, teams;
if (argc != 2) {
printf ("Usage: %s FILE\n\n", argv[0]);
printf ("One Team per line, seperated by newline, n=2, 4, ..., or %d\n", 2 * MAXTEAM);
printf ("Team n is the Groupwinner, n+1 is the Runners Up\n");
printf ("Report bugs to mbroeker@largo.homelinux.org\n");
return EXIT_FAILURE;
}
if ((f = fopen (argv[1], "r")) == NULL) {
perror ("fopen");
return EXIT_FAILURE;
}
srand (time_seed ());
teams = getTeams (f, first, first_idx, second, second_idx);
shakeTeamIdx (first_idx, second_idx, teams);
for (i = 0; i < teams; i++)
printf ("%30s vs %s\n", second[second_idx[i]], first[first_idx[i]]);
cleanup (first, second);
if (f != NULL)
fclose (f);
return EXIT_SUCCESS;
}