diff --git a/sort-c++/Makefile b/sort-c++/Makefile new file mode 100644 index 0000000..3a54daf --- /dev/null +++ b/sort-c++/Makefile @@ -0,0 +1,24 @@ +# /users/ta/cs240ta/bin/sort240test +default: main.o line.o + g++ -o sort240 main.o line.o -g + +main.o: main.cpp line.o + g++ -c main.cpp -g + +line.o: line.cpp line.h + g++ -c line.cpp -g + +clean: + rm -f sort240 *.o *.*~ + + +testmain: main.o + g++ -o sort240 main.o -g + +testline: line.cpp line.h main.cpp + g++ -c line.cpp main.cpp -g + g++ -o sort240 line.o main.o -g + +testsort: main.cpp + g++ -c main.cpp -g + g++ -o sort240 main.o -g diff --git a/sort-c++/README.md b/sort-c++/README.md new file mode 100644 index 0000000..a49a785 --- /dev/null +++ b/sort-c++/README.md @@ -0,0 +1,17 @@ +About +==== + +Simpler clone of GNU `sort` for BYU CS240. + +Build +==== + + make + ./sort240 [-rni] case1.txt + +Use +==== + + * `-i` - case insensitive sort + * `-n` - treat characters as numbers + * `-r` - reverse sort diff --git a/sort-c++/case1.txt b/sort-c++/case1.txt new file mode 100644 index 0000000..f1fe4f2 --- /dev/null +++ b/sort-c++/case1.txt @@ -0,0 +1,7 @@ +ebob ydole elou 12 +abob edole ylou 54 +obob odole elou 452 +ebob adole jlou 9 +ubob pdole qlou 0 +ibob idole clou 58 +ybob zdole glou 174 diff --git a/sort-c++/case2.txt b/sort-c++/case2.txt new file mode 100644 index 0000000..ef01456 --- /dev/null +++ b/sort-c++/case2.txt @@ -0,0 +1,12 @@ + +99 flintstone3 DINO 21 1 +652 DUCK donald 50 2 + +1314 RUBBLE Betty 78 3 +8321 FLINTSTONE1 WILMA 99 4 +7114 mouse Mickey 95 5 +0210 MOUSE2 Minnie 90 6 + +3789 FLINTSTONE2 Pebbles 78 7 +4952 flintstone4 FRED 38 8 +5785 rubble1 barney 87 9 diff --git a/sort-c++/line.cpp b/sort-c++/line.cpp new file mode 100644 index 0000000..c3acce5 --- /dev/null +++ b/sort-c++/line.cpp @@ -0,0 +1,58 @@ +#include "line.h" + +using namespace std; + +Line::Line() { + return; +} + +//TODO constructor like in class +Line::Line(char * lineOrig, int oColumnNum) { + columnNum = oColumnNum; + comparable = true; + line = new char[strlen(lineOrig)+1]; + strcpy(line,lineOrig); +} + +Line::~Line() { + return; +} + +void Line::parseLine() { + char * lineOrig = new char[strlen(line) +1]; + strcpy(lineOrig, line); + char * columnOrig = strtok(lineOrig, LINE_DELIMS); + if ( columnOrig == NULL ) { + column = NULL; + delete lineOrig; + return; + } + if (columnNum > 1) { + for (int i = 1; i < columnNum; ++i) { + columnOrig = strtok(NULL, LINE_DELIMS); + if (columnOrig == NULL) { + comparable = false; + break; + } + } + } + if (comparable) { + column = new char[strlen(columnOrig)+1]; + strcpy(column, columnOrig); + //cout << columnOrig << endl; + } else + column = NULL; + delete lineOrig; +} + +bool Line::isComparable() { + return comparable; +} + +char * Line::getColumn() const{ + return column; +} + +void Line::printLine() { + cout << line << endl; +} \ No newline at end of file diff --git a/sort-c++/line.h b/sort-c++/line.h new file mode 100644 index 0000000..d97e539 --- /dev/null +++ b/sort-c++/line.h @@ -0,0 +1,29 @@ +#include +#include +#include + + +#define LINE_DELIMS " \t\n\r" +#define MAX_LINE_LENGTH 10240 + +class Line { +private: + char * line; + char * column; + bool comparable; + int columnNum; + bool sortInsensitive; + bool sortNumber; + bool sortReverse; +public: + Line(); + Line(char*, int); + //Line(char*); + ~Line(); + char * getColumn() const; + int compare(char *); + //static int qCompare(const void *, const void *); + void printLine(); + bool isComparable(); + void parseLine(); +}; \ No newline at end of file diff --git a/sort-c++/main.cpp b/sort-c++/main.cpp new file mode 100644 index 0000000..960d5d2 --- /dev/null +++ b/sort-c++/main.cpp @@ -0,0 +1,141 @@ +#include "sort240.h" + +using namespace std; + +int qCompare( const void* m, const void* n ) { + Line * myLineA = *((Line**) m); + Line * myLineB = *((Line**) n); + + if (myLineA->getColumn() == NULL) + return -1; + if (myLineB->getColumn() == NULL) + return 1; + + int result = 0; + + if (sortInsensitive) { + //cout << "I" << endl; + result = strcasecmp(myLineA->getColumn(), myLineB->getColumn()); + } else { + if (sortNumber) { + //cout << "N" << endl; + result = (atoi(myLineA->getColumn()) > atoi(myLineB->getColumn())) ? 1 : -1; + } else { + //cout << "X" << endl; + result = strcmp(myLineA->getColumn(), myLineB->getColumn()); + } + } + + if (sortReverse) { + //cout << "R" << endl; + result *= -1; + } + + /* + cout << "\nA: " << myLineA->getColumn() << endl; + cout << "B: " << myLineB->getColumn() << endl; + cout << "R: " << result << endl; + */ + + return result; +} + +int main (int argc, char * argv[]) { + if (argc != 3 && argc !=4) { + cerr << "Usage: sort240 [-rni] \n" << endl; + return BAD_ARGS; + } + + int i = 1; + + if (argv[i][0] == '-') { + int len = strlen(argv[i]); + for (int j = 1; j < len; j++) { + switch (argv[i][j]) { + case 'r': + sortReverse = true; + break; + case 'i': + if (!sortNumber) { + sortInsensitive = true; + } else { + //cout << "Ignoring case insensitivity for numbers." << endl; + } + break; + case 'n': + sortNumber = true; + sortInsensitive = false; + break; + } + } + ++i; + } + + column = atoi(argv[i]); + fileName = argv[++i]; + + openFile(); + + parseFile(); + + qsort(myLines, length, sizeof(Line**), qCompare); + + for (int k = 0; k < length; ++k) { + myLines[k]->printLine(); + } + + //delete sort; + + return CLEAN; +} + +void openFile() { + //cout << "Opening file" << endl; + memset(lines, 0, sizeof(lines)); + + // Open the file or exit + ifstream file; + file.open(fileName); + if (!file.is_open()) { + cerr << "Unable to open file: " << fileName << "\n" << endl; + exit(BAD_FILE); + } + + // Read up to 1024 lines of 1024 char length + lastLine = 0; + char line[CHARS_PER_LINE]; + char * lineCopy; + while (file.getline(line, CHARS_PER_LINE)) { + if ('\n' == line[0] || '\r' == line[0]) { + continue; + } + lineCopy = new char[strlen(line) + 1]; + strcpy(lineCopy, line); + if (NULL == strtok(line, "\n\t\r ")) + { + continue; + } + lines[lastLine] = lineCopy; + lastLine++; + } + file.close(); +} + +int parseFile() { + //cout << "Parsing File" << endl; + length = 0; + curLine = 0; + + // TODO off by one? + myLines = new Line*[lastLine]; + while (curLine < lastLine) { + char * lineCopy = new char[strlen(lines[curLine])]; + strcpy(lineCopy, lines[curLine]); + myLines[curLine] = new Line(lines[curLine], column); + myLines[curLine]->parseLine(); + //cout << myLines[curLine]->getColumn() << endl; + ++curLine; + //delete lineCopy; + } + length = curLine; +} diff --git a/sort-c++/sort240.h b/sort-c++/sort240.h new file mode 100644 index 0000000..c9c51e9 --- /dev/null +++ b/sort-c++/sort240.h @@ -0,0 +1,54 @@ +/* + * Objective: + * Read commandline params including options + * Parse file line-by-line + * Parse line column-by-column while preserving lines + * Sort lines by column + */ + +#include +#include +#include +#include +#include "line.h" + +#define CLEAN 0 +#define BAD_ARGS -3 +#define BAD_FILE -4 + +#define LINES_IN_FILE 10240 +#define CHARS_PER_LINE 10240 +#define DELIMS " \t\n\r" +#define WHITE_SPACE " \t" + + + char * fileName; // Input file + char * lines[LINES_IN_FILE]; // Input file line-by-line in array + char * disallowed[LINES_IN_FILE]; // Lines that match Disallowed: + int curLine; // The current line of the file + int lastLine; + int selectedColumn; + int length; // The number of disallowed paths + void openFile(); + int parseFile(); + bool sortInsensitive = false; + bool sortReverse = false; + bool sortNumber = false; + int column; + void sort(); + char * wsFix(char *); + Line ** myLines; +// public: +// Sort240(int, char *, bool, bool, bool); +// ~Sort240(); + void setCaseInsensitive(bool); + void setIntegerSort(bool); + void setReverse(bool); + //int * qCompare(const void *, const void *); + +//bool sortInsensitive; +//bool sortNumber = false; +//bool sortReverse = false; +//bool Sort240::sortInsensitive = false; +//bool Sort240::sortReverse = false; +//bool Sort240::sortNumber = false;