Kursach

Run Settings
LanguageC
Language Version
Run Command
#include <stdlib.h> #include <stdio.h> #include <limits.h> #define boolean int #define false 0 #define true 1 #ifdef linux #define clear() printf("\x1B[2J\x1B[H") #else #define clear() system("cls") #endif //Utilitary boolean isDigit(char c); short int charToDigit(char c); int length(char* str); boolean contains(char c, char* array); void checkMemoryFault(void* ptr); boolean isLargerThan(char* word1, char* word2); char toLowercase(char c); //Input functions char* gets(); int getUnsIntOrDefault(); //pGUI int dmenu(int n, char* entries[n]); int startMenu(); int workMenu(); int inputMenu(); //UX void printErrorAndExit(char* message); void clearToHeader(); void askEnter(); void printText(char** text, int length); //Common outputs void printHeader(); void printTask(); void wrongInputMessage(char* addInfo); void sayGoodbye(); //Real logic boolean workLoop(); void inputData(char** sepStorage, char*** textStorage, int* textLengthStorage); void formNewText(char* separators, char** inText, int inTextLength, char*** newTextStorage, int* newTextLengthStorage); //Some work with text void splitString(char* str, char* separators, char*** wordsStorage, char*** sepseqStorage, int* wordsCount); void sortWords(char** words, int wordsCount); char* assemble(char** words, char** sepseqs, int wordsCount); boolean trimShortestOrSignal(char** words, int wordsCount); int main(){ boolean exitRequested = false; int answer; while(!exitRequested){ clearToHeader(); answer = startMenu(); switch(answer){ case -1: wrongInputMessage(""); break; case 0: printTask(); askEnter(); break; case 1: exitRequested = workLoop(); break; case 2: exitRequested = true; break; } } sayGoodbye(); return 0; } //---- //Logic //---- boolean workLoop(){ boolean isGlobalExitRequested = false; char* separators = NULL; char** inText = NULL; int inTextLength; char** newText = NULL; int newTextLength; boolean isFormed = false; inputData(&separators, &inText, &inTextLength); checkMemoryFault((void*) separators); checkMemoryFault((void*) inText); boolean exitRequested = false; int answer; while(!exitRequested){ clearToHeader(); answer = workMenu(); switch(answer){ case -1: wrongInputMessage(""); break; case 0: printTask(); askEnter(); break; case 1: printText(inText, inTextLength); askEnter(); break; case 2: if(!isFormed){ formNewText(separators, inText, inTextLength, &newText, &newTextLength); checkMemoryFault(newText); isFormed = true; } printText(newText, newTextLength); askEnter(); break; case 3: printf("\nИсходный текст:\n"); printText(inText, inTextLength); if(!isFormed){ formNewText(separators, inText, inTextLength, &newText, &newTextLength); checkMemoryFault(newText); isFormed = true; } printf("Cформированный текст:\n"); printText(newText, newTextLength); askEnter(); break; case 4: printf("Символы-разделители: %s\n", separators); askEnter(); break; case 5: exitRequested = true; break; case 6: isGlobalExitRequested = true; exitRequested = true; break; } } free(separators); int i; for(i=0; i<inTextLength; i++){ free(inText[i]); } free(inText); if(isFormed){ for(i=0; i<newTextLength; i++){ free(newText[i]); } free(newText); } return isGlobalExitRequested; } void inputData(char** sepStorage, char*** textStorage, int* textLengthStorage){ checkMemoryFault(sepStorage); (*sepStorage) = NULL; checkMemoryFault(textStorage); (*textStorage) = NULL; checkMemoryFault(textLengthStorage); boolean exitRequested = false; int answer; while(!exitRequested){ clearToHeader(); printf("Введите символы-разделители: "); (*sepStorage) = gets(); checkMemoryFault(*sepStorage); if((*sepStorage)[0]=='\0'){ wrongInputMessage("Разделителей должно быть ненулевое количество.\n"); }else{//continue printf("\n"); printf("Введите количество строк в тексте: "); (*textLengthStorage) = getUnsIntOrDefault(-1); if((*textLengthStorage)<=0){ wrongInputMessage("Ожидалось, что вы введёте число (большее нуля).\n"); }else{//continue printf("\n"); (*textStorage) = (char**) malloc( (*textLengthStorage) * sizeof(char*) ); checkMemoryFault(*textStorage); int i; for(i=0; i<(*textLengthStorage); i++){ printf("Введите строку №%d: ", (i+1)); (*textStorage)[i] = gets(); checkMemoryFault((*textStorage)[i]); } printf("\n"); answer = inputMenu(); switch(answer){ case -1: wrongInputMessage("Введённые даные будут сохранены.\n"); exitRequested = true; break; case 0: exitRequested = true; break; case 1: //do nothing break; } }} } } void formNewText(char* separators, char** inText, int inTextLength, char*** newTextStorage, int* newTextLengthStorage){ checkMemoryFault((void*) separators); checkMemoryFault((void*) inText); if(inTextLength<=0){ printErrorAndExit("Произошла внутренняя ошибка.\n"); } int i; for(i=0; i<inTextLength; i++){ checkMemoryFault((void*) inText[i]); } checkMemoryFault((void*) newTextStorage); (*newTextStorage) = NULL; checkMemoryFault((void*) newTextLengthStorage); char** words; char** sepseqs; int wordsCount; int j; boolean haveToDelete; (*newTextLengthStorage)=0; for(i=0; i<inTextLength; i++){ splitString(inText[i], separators, &words, &sepseqs, &wordsCount); if(wordsCount!=0) checkMemoryFault(words); checkMemoryFault(sepseqs); for(j=0; j<wordsCount+1; j++){ if(j!=wordsCount) checkMemoryFault(words[j]); checkMemoryFault(sepseqs[j]); } haveToDelete = (wordsCount==0) ?false :trimShortestOrSignal(words, wordsCount); if(!haveToDelete){ if(wordsCount>1) sortWords(words, wordsCount); (*newTextStorage) = (char**) realloc((*newTextStorage), ((*newTextLengthStorage)+1)*sizeof(char*)); (*newTextStorage)[(*newTextLengthStorage)] = assemble(words, sepseqs, wordsCount); (*newTextLengthStorage)++; } } } void splitString(char* str, char* separators, char*** wordsStorage, char*** sepseqStorage, int* wordsCount){ checkMemoryFault((void*) str); checkMemoryFault((void*) separators); checkMemoryFault((void*) wordsStorage); checkMemoryFault((void*) sepseqStorage); checkMemoryFault((void*) wordsCount); *wordsStorage = NULL; *sepseqStorage = (char**) malloc(sizeof(char*)); checkMemoryFault((void*) *sepseqStorage); (*wordsCount) = 0; boolean isReadingWord = false; boolean isEndOfSeq=false; char* curSeq = (char*) malloc(sizeof(char)); checkMemoryFault((void*) curSeq); int curSeqSize = 0; int i=-1; //it will be immediately increased to 0 do{ i++; if(isReadingWord){ if(contains(str[i], separators) || str[i]=='\0'){ isReadingWord = false; //Word is readen now curSeq[curSeqSize]='\0'; (*wordsStorage)[*wordsCount] = curSeq; (*wordsCount)++ ; //String anyway ends with sep.seq., not word -- so THERE IS sep.seq. after ANY word *sepseqStorage = (char**) realloc(*sepseqStorage, (*wordsCount+1)*sizeof(char*)); checkMemoryFault((void*) *sepseqStorage); if(str[i]!='\0'){ //get ready to new input isEndOfSeq = true; //Flag to flush curSeq } }else{ isEndOfSeq = false; } }else{ if(!contains(str[i], separators)){ isReadingWord = true; //Separators sequence is readen now curSeq[curSeqSize]='\0'; (*sepseqStorage)[*wordsCount] = curSeq; if(str[i]!='\0'){ //get ready to new input *wordsStorage = (char**) realloc(*wordsStorage, (*wordsCount+1)*sizeof(char*)); checkMemoryFault((void*) *wordsStorage); isEndOfSeq = true; //Flag to flush curSeq } }else{ isEndOfSeq = false; } } if(isEndOfSeq){ curSeq = (char*) malloc(sizeof(char)); checkMemoryFault((void*) curSeq); curSeqSize=0; } //Regular actions -- just remember our char if(str[i]!='\0'){ //No need to remember that \0 ;) curSeq[curSeqSize] = str[i]; curSeq = (char*) realloc(curSeq, sizeof(char)*(++curSeqSize+1)); checkMemoryFault((void*) curSeq); } }while(str[i]!='\0'); if(!isReadingWord){ //So, we have an empty last separators sequence (*sepseqStorage)[*wordsCount] = (char*) malloc(sizeof(char)); checkMemoryFault((void*) (*sepseqStorage)[*wordsCount]); (*sepseqStorage)[*wordsCount][0] = '\0'; } } boolean trimShortestOrSignal(char** words, int countWords){ checkMemoryFault(words); int i; for(i=0; i<countWords; i++){ checkMemoryFault(words[i]); } if(countWords<=0){ printErrorAndExit("Произошла внутренняя ошибка.\n"); } int ind1; if(countWords == 1){ int min=INT_MAX; int count = 0; ind1 = -1; int len; for(i=0; i<countWords; i++){ len = length(words[i]); if(len<min){ min = len; count = 1; ind1 = i; }else if(len == min){ count++; } } if(count>1) return true; }else{ ind1 = 0; } free(words[ind1]); words[ind1] = (char*) malloc(sizeof(char)); checkMemoryFault(words[0]); words[ind1][0]='\0'; return false; } void sortWords(char** words, int wordsCount){ if(wordsCount<2) return; checkMemoryFault(words); int i; for(i=0; i<wordsCount; i++){ checkMemoryFault(words[i]); } i=0; char* swap; while(i+1<wordsCount){ if(isLargerThan(words[i+1], words[i])){ swap = words[i+1]; words[i+1] = words[i]; words[i] = swap; if(i>0){ i--; }else{ i++; } }else{ i++; } } } char* assemble(char** words, char** separators, int wordsCount){ if(wordsCount!=0) checkMemoryFault(words); checkMemoryFault(separators); char* str = (char*) malloc(sizeof(char)); checkMemoryFault(str); int size=0; int i,j; for(i=0; i<wordsCount+1; i++){ j=0; checkMemoryFault(separators[i]); while(separators[i][j]!='\0'){ str[size] = separators[i][j]; str = (char*) realloc(str, sizeof(char)*(++size+1)); checkMemoryFault(str); j++; } if(i!=wordsCount){ j=0; checkMemoryFault(words[i]); while(words[i][j]!='\0'){ str[size] = words[i][j]; str = (char*) realloc(str, sizeof(char)*(++size+1)); checkMemoryFault(str); j++; } } } str[size]='\0'; return str; } //---- //Helpful littlies //---- void checkMemoryFault(void* ptr){ if(ptr == NULL){ printErrorAndExit("Ошибка при работе с памятью. "); } } void printErrorAndExit(char* message){ printf("%sПосле нажатия Enter программа завершит своё выполнение.\n", message); askEnter(); exit(-1); } void clearToHeader(){ clear(); printHeader(); } void askEnter(){ printf("Нажмите Enter для продолжения..."); getchar(); } int length(char* str){ checkMemoryFault((void*)str); int i=0; while(str[i]!='\0'){ i++; } return i; } boolean isDigit(char c){ if(c<48 || c>57) return false; return true; } short int charToDigit(char c){ return ((short int)c)-48; } boolean contains(char c, char* array){ checkMemoryFault(array); int i=0; while(array[i]!='\0'){ if(c == array[i]) return true; i++; } return false; } void printText(char** text, int length){ checkMemoryFault((void*) text); printf("\n"); int i; for(i=0; i<length; i++){ checkMemoryFault((void*) text[i]); printf("%s\n", text[i]); } printf("\n"); } boolean isLargerThan(char* word1, char* word2){ checkMemoryFault(word1); checkMemoryFault(word2); if(word1[0]=='\0') return false; if(word2[0]=='\0') return true; int i = 0; while(word1[i]!='\0' && word2[i]!='\0'){ if((int) toLowercase(word1[i]) != (int) toLowercase(word2[i])){ return ((int) toLowercase(word1[i]) < (int) toLowercase(word2[i])); } i++; } if(word1[i]=='\0'){ return true; } return false; } char toLowercase(char c){ //assert letters are given if(((int)c)<97) return (char)((int)c + 32); return c; } //---- //Input functions //---- char* gets(){ char* str = (char*) malloc(sizeof(char)); checkMemoryFault(str); int i = 0; while( (str[i] = getchar()) != '\n' ){ str = (char*) realloc(str, sizeof(char)*(++i+1)); checkMemoryFault(str); } str[i]='\0'; return str; } int getUnsIntOrDefault(int defaultValue){ int ret = 0; char c; boolean isDefault = false; while( (c = getchar()) != '\n' ){ if(!isDigit(c)){ isDefault = true; } if(!isDefault){ ret *= 10; ret += charToDigit(c); } } if(isDefault){ return defaultValue; } return ret; } void wrongInputMessage(char* addInfo){ printf("Не удалось распознать ввод. %s", addInfo); askEnter(); } //---- //pGUI //---- int startMenu(){ char* entries[3]={"Вывести текст задания", "Ввести данные и начать работу с ними", "Завершить работу"}; return dmenu(3, entries); } int workMenu(){ char* entries[7]={"Вывести текст задания", "Вывести исходный текст", "Вывести сформированный текст", "Вывести оба (исходный и сформированный) текста", "Вывести символы-разделители", "Завершить работу с введёнными данными", "Завершить работу программы"}; return dmenu(7, entries); } int inputMenu(){ char* entries[2]={"Продолжить работу", "Ввести данные заново"}; return dmenu(2, entries); } int dmenu(int n, char* entries[n]){ printf("Выберите действие из меню, путём ввода его номера.\n"); int i; for(i=0; i<n; i++){ printf("%d. %s\n", i+1, entries[i]); } printf("Ваш выбор: "); int result = getUnsIntOrDefault(-1); //Checking correctness if(result<=0 || result>n) return -1; return result-1; } //---- //Common outputs //---- void printHeader(){ printf("----------------------------------------------------\n"); printf("Курсовая работа за первый семестр \t /\\_/\\\n"); printf("Вариант №18 \t=( °w° )=\n"); printf("Выполнил Соковых Пётр \t ) ( //\n"); printf("Факультет КТИ, группа 6305 \t (__ __)//\n"); printf("----------------------------------------------------\n"); } void printTask(){ printf("\nЗадание:\n\n"); printf("Ввести строку символов разделителей и массив строк текста с заданным количесвтом строк. "); printf("Из строк введённого текста сформировать другой текст, в котором слова будут распологаться "); printf("в алфавитном порядке с сохранением очередности расположения символов разделителей в исходных строках. "); printf("Одновременно из строк удалить слова с минимальным в этой строке количеством символов и всю строку, "); printf("если таких слов в строке более одного."); printf("Вывести исходный и сформированный текст.\n\n"); } void sayGoodbye(){ printf("\nРабота завершена.\n"); }
Editor Settings
Theme
Key bindings
Full width
Lines