// treeCapitals.cpp : Questo file contiene la funzione 'main', in cui inizia e termina l'esecuzione del programma. // #include #include #include #include /* Maximum length of capital names */ #define STRMAX 40 /* Maximum length of rows */ #define MAX_ROW 80 struct node { unsigned long population; char capital[STRMAX + 1]; struct node* left_child; struct node* right_child; }; struct node* createNode(char* capitalName, unsigned long capitalPopulation) { struct node* newNode = (struct node*)malloc(sizeof(struct node)); if (newNode != NULL) { strcpy(newNode->capital, capitalName); newNode->population = capitalPopulation; newNode->left_child = NULL; newNode->right_child = NULL; } return(newNode); } // insertion struct node* insert(struct node* root, struct node* newNode) { //searching for the place to insert if (root == NULL) return(newNode); else if (newNode->population > root->population) // population is greater. Should be inserted to the right root->right_child = insert(root->right_child, newNode); else // population is smaller and should be inserted to left root->left_child = insert(root->left_child, newNode); return(root); } // insertion by capitals names order struct node* insertByCapitalsNames(struct node* root, struct node* newNode) { //searching for the place to insert if (root == NULL) return(newNode); else if (strcmp(newNode->capital, root->capital) > 0) // newNode capital is greater. Should be inserted to the right root->right_child = insertByCapitalsNames(root->right_child, newNode); else // newNode capital is smaller and should be inserted to left root->left_child = insertByCapitalsNames(root->left_child, newNode); return(root); } // searching operation struct node* searchItem(struct node* root, char* capitalToSearch) { if ((root == NULL) || (strcmp(root->capital, capitalToSearch) == 0)) //if root->capital is the capital then the element is found return root; else if (strcmp(capitalToSearch, root->capital) > 0) // capitalToSearch is greater, so we will search the right subtree return searchItem(root->right_child, capitalToSearch); else // capitalToSearch is smaller than the data, so we will search the left subtree return searchItem(root->left_child, capitalToSearch); } void printTree(struct node* root) { if (root != NULL) // checking if the root is not null { printTree(root->left_child); // traversing left child printf("%-28s: population %9d\n", root->capital, root->population); // printing data at root //printf(":%s: population %9d\n", root->capital, root->population); // printing data at root printTree(root->right_child); // traversing right child } } void saveTree(FILE* fo, struct node* root) { if (root != NULL) // checking if the root is not null { if (fprintf(fo, "%s;%d\n", root->capital, root->population) < 0) { perror("Error saving data to file"); return; } saveTree(fo, root->left_child); // traversing left child saveTree(fo, root->right_child); // traversing right child } } void printTreeDescending(struct node* root) { if (root != NULL) // checking if the root is not null { printTreeDescending(root->right_child); // traversing right child printf("%-28s: population %9d\n", root->capital, root->population); // printing data at root printTreeDescending(root->left_child); // traversing left child } } int updateData(FILE* fi, struct node* root, struct node* rootC) { char row[MAX_ROW + 1]; while (!feof(fi)) { if (fgets(row, MAX_ROW, fi) != row) { if (feof(fi)) { break; } else { perror("Error reading file input"); return(3); } } char capitalName[STRMAX + 1]; unsigned long capitalPopulation; char* t; if ((t = strtok(row, ";")) != NULL) { strcpy(capitalName, t); if ((t = strtok(NULL, ";")) != NULL) { capitalPopulation = atol(t); } } else { printf("Error reading tokens from capitals population file"); return(4); } //printf("Capital %s - population %d\n", capitalName, capitalPopulation); struct node* newNode = createNode(capitalName, capitalPopulation); if (newNode != NULL) { root = insert(root, newNode); } else { printf("Error creating newNode"); return(5); } newNode = createNode(capitalName, capitalPopulation); if (newNode != NULL) { rootC = insertByCapitalsNames(rootC, newNode); } else { printf("Error creating newNode"); return(5); } } return(0); } int main(int argc, char* argv[]) { struct node* root = NULL; /* pointer to the root item of the tree ordered by population */ struct node* rootC = NULL; /* pointer to the root item of the tree ordered by capitals names */ char row[MAX_ROW + 1]; if (argc != 2) { printf("Error: usage %s capitals_population_filename\n", argv[0]); return(1); } FILE* fi = fopen(argv[1], "r"); if (fi == NULL) { perror("Error opening input file\n"); return(2); } while (!feof(fi)) { if (fgets(row, MAX_ROW, fi) != row) { if (feof(fi)) { break; } else { perror("Error reading file input"); return(3); } } char capitalName[STRMAX + 1]; unsigned long capitalPopulation; char* t; if ((t = strtok(row, ";")) != NULL) { strcpy(capitalName, t); if ((t = strtok(NULL, ";")) != NULL) { capitalPopulation = atol(t); } } else { printf("Error reading tokens from capitals population file"); return(4); } //printf("Capital %s - population %d\n", capitalName, capitalPopulation); struct node* newNode = createNode(capitalName, capitalPopulation); if (newNode != NULL) { root = insert(root, newNode); } else { printf("Error creating newNode"); return(5); } newNode = createNode(capitalName, capitalPopulation); if (newNode != NULL) { rootC = insertByCapitalsNames(rootC, newNode); } else { printf("Error creating newNode"); return(5); } } fclose(fi); bool menu = true; while (menu) { printf("[1] Print tree in ascending order of population\n"); printf("[2] Print tree in decending order of population\n"); printf("[3] Search capital\n"); printf("[4] Load new capitals and population\n"); printf("[5] Save capitals and population\n"); printf("[6] Exit\n"); printf("\nMake your choice:"); char choice[STRMAX + 1]; if (gets_s(choice, STRMAX) == NULL) { printf("Error reading choice\n"); return(6); } int myChoice = atoi(choice); switch (myChoice) { case 1: printf("Printing current tree in ascending order of population\n"); printTree(root); break; case 2: printf("Printing current tree in decending order of population\n"); printTreeDescending(root); break; case 3: { char capitalName[STRMAX + 1]; printf("\nInsert capital name:"); if (gets_s(capitalName, STRMAX) == NULL) { printf("Error reading capital name\n"); return(7); } else { printf("Capital name to be searched %s\n", capitalName); } struct node* capitalFound = searchItem(rootC, capitalName); if (capitalFound != NULL) { printf("%s: population %d\n", capitalFound->capital, capitalFound->population); } else { printf("Capital %s not found\n", capitalName); } break; } case 4: { printf("Loading new capitals..\n"); char filenameToRead[MAX_ROW + 1]; printf("\nInsert filename with new capitals:"); if (gets_s(filenameToRead, MAX_ROW) == NULL) { printf("Error reading file name\n"); return(9); } FILE* fi = fopen(filenameToRead, "r"); if (fi != NULL) { int retc = updateData(fi, root, rootC); if (retc != 0) { printf("Error updating capitals data\n"); } fclose(fi); } else { perror("Error opening file"); printf("Error opening file '%s.\n", filenameToRead); } break; } case 5: { char filenameToSave[MAX_ROW + 1]; printf("\nInsert filename where saving data:"); if (gets_s(filenameToSave, MAX_ROW) == NULL) { printf("Error reading file name\n"); return(7); } FILE* fo = fopen(filenameToSave, "r"); if (fo != NULL) { // Close the file after checking existence fclose(fo); printf("File '%s' exists.\n", filenameToSave); printf("Do you want to overwrite it (Y/N):"); if (gets_s(choice, STRMAX) == NULL) { printf("Error reading choice\n"); return(11); } char c = choice[0]; if ((c == 'n') || (c == 'N')) printf("\nPlease choose a different filename\n"); else if ((c == 'y') || (c == 'Y')) { printf("\nSaving data in file '%s'.\n", filenameToSave); fo = fopen(filenameToSave, "w"); if (fo == NULL) { perror("Error opening file for saving data"); return(8); } saveTree(fo, root); fclose(fo); } else printf("\nBad choice. Please choose a different filename\n"); } else { printf("Saving data in file '%s'.\n", filenameToSave); fo = fopen(filenameToSave, "w"); if (fo == NULL) { perror("Error opening file for saving data"); return(8); } saveTree(fo, root); fclose(fo); } break; } case 6: menu = false; break; default: printf("Choice %s is a bad choice\n", choice); break; } } return(0); }