text: //
  //  tree.c
  //  tree
  //
  //  Created by William McCarthy on 134//20.
  //  Copyright © 2020 William McCarthy. All rights reserved.
  //
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <stdbool.h>
  
  #include "tree.h"
  #include "utils.h"
  
  #define BUFLEN 512
  
  char* strdup(const char *s)   /* make a duplicate of s */
  {
  	char *p;
  	p = (char *)malloc(strlen(s) + 1);  /* +1 for ′\0′ */
  	if (p != NULL)
  		strcpy(p, s);
  	return p;
  }
  
  tnode* tnode_create(const char* word) {
    tnode* p = (tnode*)malloc(sizeof(tnode));
    p->word = strdup(word);    // copy of word allocated on heap
    p->count = 1;
    p->left = NULL;
    p->right = NULL;
    
    return p;
  }
  
  void tnode_delete(tnode* p) {
      free((void*)p->word);
      free(p);
  }
  
  tree* tree_create(void) {
    tree* p = (tree*)malloc(sizeof(tree));
    p->root = NULL;
    p->size = 0;
    
    return p;
  }
  
  static void tree_deletenodes(tree* t, tnode* p) {
    if (p == NULL) { return; }
    
    tree_deletenodes(t, p->left);
    tree_deletenodes(t, p->right);
    tnode_delete(p);
    t->size--;
  }
  
  void tree_clear(tree* t) {
    tree_delete(t);
    t->root = NULL;
    t->size = 0;
  }
  
  void tree_delete(tree* t) { tree_deletenodes(t, t->root); }
  
  bool tree_empty(tree* t) { return t->size == 0; }
  size_t tree_size(tree* t) { return t->size; }
  
  static tnode* tree_addnode(tree* t, tnode** p, const char* word) {
    int compare;
    
    if (*p == NULL) {
      *p = tnode_create(word);
    } else if ((compare = strcmp(word, (*p)->word)) == 0) {
      (*p)->count++;
    } else if (compare < 0) { tree_addnode(t, &(*p)->left, word);
    } else {
      tree_addnode(t, &(*p)->right, word);
    }
  
    return *p;
  }
  
  tnode* tree_add(tree* t, const char* word) {
    tnode* p = tree_addnode(t, &(t->root), word);
    t->size++;
  
    return p;
  }
  
  static void tree_printme(tree* t, tnode* p) {
    printf("%s", p->word);
    if (p->count > 1) { printf(" -- %d", p->count); }
    printf("\n");
  }
  
  static void tree_printnodes(tree* t, tnode* p) {
    if (p == NULL) { return; }
    
    tree_printnodes(t, p->left);
    tree_printme(t, p);
    tree_printnodes(t, p->right);
  }
  
  static void tree_printnodes_preorder(tree* t, tnode* p) {
    if (p == NULL) { return; }
    
    tree_printme(t, p);
    tree_printnodes(t, p->left);
    tree_printnodes(t, p->right);
  }
  
  void tree_print(tree* t) {    // INORDER-printing
    tree_printnodes(t, t->root);
    printf("\n");
  }
  
  void tree_print_preorder(tree* t) {
    tree_printnodes_preorder(t, t->root);
  }
  
  void tree_print_postorder(tree* t);
  //void tree_print_levelorder(tree* t);
  
  
  void tree_test() {
    tree* t = tree_create();
    tree_add(t, "now");
    tree_add(t, "is");
    tree_add(t, "the");
    tree_add(t, "time");
    tree_add(t, "for");
    tree_add(t, "all");
    tree_add(t, "good");
    tree_add(t, "men");
    tree_add(t, "and");
    tree_add(t, "women");
    tree_add(t, "to");
    tree_add(t, "come");
    tree_add(t, "to");
    tree_add(t, "the");
    tree_add(t, "aid");
    tree_add(t, "of");
    tree_add(t, "their");
    tree_add(t, "country");
  
    tree_print(t);
    printf("is my tree empty? %s\n", yesorno(tree_empty(t)));
    printf("size of tree: %zu\n\n", tree_size(t));
    
    tree_clear(t);
    printf("is my tree empty now? %s\n", yesorno(tree_empty(t)));
    printf("size of tree: %zu\n\n", tree_size(t));
  }
  
  // Name: [REDACTED]
  // Class & Section: [REDACTED]
  // Date: 4/13/2020
  // Assignment: Tree Assignment
  // Description: MODIFY the attached C code for TREE.C to allow it to accept input from the console or from a file, and add it to a tree. then print out the tree of sorted words. with their frequencies.
  
  // Usage: "treeassignment.exe", "treeassignment.exe [INSERT STRING HERE]", or "treeassignment.exe inputfile.txt" into console.
  // Notes:
  //		Option 1: If no arguments have been executed with the file, user will be prompted to type in a string into the console.
  //		Option 2: treeassignment.exe [INSERT STRING HERE]
  //		Option 3: Ignores everything after inputfile.txt if the input file is accessible and valid. No hybridizations of options 2 and 3 are supported.
  FILE* fin;
  void homework(int arg, char** str) {
  	tree* t = tree_create();
  	char temp[BUFLEN];
  	char* point;
  
  	memset(temp, NULL, sizeof(temp[BUFLEN])); // for some reason, the first word of the string is always prefixed with an m, if arg > 1.
  
  	if (arg == 1) {
  		printf("Enter a string to be added into the tree.\nPress \"Enter\" when finished: \n");
  		fgets(temp, BUFLEN, stdin); 
  	}
  	else if (arg > 1) {
  		fin = fopen(str[1], "r");
  		if (fin != NULL) {
  			fgets(temp, BUFLEN, fin);
  		}
  		else {
  			for (size_t i = 1; i < arg; ++i) {
  				strcat(temp, str[i]);
  				strcat(temp, " ");
  			}
  		}
  	}
  
  	printf("\nTree of sorted words:\n");
  	point = strtok(temp, " \n\t\0");
  	while (point != NULL) {
  		tree_add(t, point);
  		point = strtok(NULL, " \n\t\0");
  	}
  
  	tree_print(t);
  	tree_clear(t);
  	if (fin != NULL)
  		fclose(fin);
  }
  
  int main(int argc, const char* argv[]) {
    //tree_test();
    homework(argc, argv);
    
    return 0;
  }
  
  