/* compile with `clang -std=c99 -Wall -o wordnum wordnum_commented.c` *//* compile with `clang -std=c99 -Wall -o wordnum wordnum_commented.c` */Include the usual header files.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>Store all state for the exam in one big struct. Two tables with allocated capacity and actual item count. Putting it in a struct is not necessary, this could be global variables.
typedef struct exam {
char **wordTable;
int wordTableSize;
int words;
int **numTable;
int numTableSize;
int nums;
} exam_t;Exam gave the function names for how to split up the solution. Each function
takes the whole exam_t structure because it might need several parts.
void allocAndReadInput(exam_t *exam);
void sortNum(exam_t *exam);
void output(exam_t *exam);
void freeMemory(exam_t *exam);int main() {Static struct initialization of all state.
exam_t exam = {
.wordTable = calloc(16, sizeof(char *)),
.wordTableSize = 16,
.words = 0,
.numTable = calloc(16, sizeof(int *)),
.numTableSize = 16,
.nums = 0
};Read in input, sort numbers, output, and free dynamic memory.
allocAndReadInput(&exam);
sortNum(&exam);
output(&exam);
freeMemory(&exam);
return 0;
}read input, distinguish between word and number, check for duplicated words, allocate memory + reallocate if necessary, store in wordTable / numTable
void allocAndReadInput(exam_t *exam) {
char buffer[64];
do {read at most 63 characters
scanf("%63s", (char *) &buffer);end program if it is “.”
if (strcmp(".", buffer) == 0) {
return;
}try to convert to number
char *rest;
int num = strtol(buffer, &rest, 10);no rest, this is a valid number
if (*rest == '\0') {make space if table capacity is too small
if (exam->nums == exam->numTableSize) {
exam->numTableSize *= 2;
exam->numTable = realloc(exam->numTable,
exam->numTableSize * sizeof(int *));
}
exam->numTable[exam->nums] = malloc(sizeof(int));
*exam->numTable[exam->nums] = num;
exam->nums += 1;
}some rest, this is not an number but a word.
else {
bool found = false;search for word in table
for (int i = 0; i < exam->words; i++) {
if (strcmp(buffer, exam->wordTable[i]) == 0) {
found = true;
break;
}
}skip duplicate word
if (found) {
continue;
}make space if table capacity is too small
if (exam->words == exam->wordTableSize) {
exam->wordTableSize *= 2;
exam->wordTable = realloc(exam->wordTable,
exam->wordTableSize * sizeof(char *));
}insert duplicate of word in table
exam->wordTable[exam->words] = strdup(buffer);
exam->words += 1;
}
} while (1);
}void sortNum(exam_t *exam) {
for (int i = 0 ; i < exam->nums - 1; i++) {
for (int j = 0 ; j < exam->nums - i - 1; j++) {swap down if larger
if (*exam->numTable[j] > *exam->numTable[j + 1]) {
int *tmp = exam->numTable[j];
exam->numTable[j] = exam->numTable[j + 1];
exam->numTable[j + 1] = tmp;
}
}
}
}void output(exam_t *exam) {print both wordTable and numTable
for (int i = 0; i < exam->words; i++) {
printf("%s ", exam->wordTable[i]);
}
printf("\n");
for (int i = 0; i < exam->nums; i++) {
printf("%i ", *exam->numTable[i]);
}
}void freeMemory(exam_t *exam) {
for (int i = 0; i < exam->words; i++) {
free(exam->wordTable[i]);
exam->wordTable[i] = NULL;
}
for (int i = 0; i < exam->nums; i++) {
free(exam->numTable[i]);
exam->numTable[i] = NULL;
}
free(exam->wordTable);
exam->wordTable = NULL;
exam->words = 0;
free(exam->numTable);
exam->nums = 0;
exam->numTable = NULL;
}