I've done a program that computes (by a DB itself using fstream
) patients from a hospital. It has output functions (one for ostream using iomanip
and one for ofstream
and fstream
) and input ( get()
). As a requirement, I had to use selection sort and binary search that spend a damn memory (at least the way I had to do the binary search) data in a raw way. I implemented the following:
#include <cstring>
#include <iomanip>
class patientType
{
private:
char* first_name_t;
char* second_name_t;
unsigned id_t;
public:
patientType()
{
}
void get()
{
char* first_name = new char[128];
char* second_name = new char[128];
unsigned id;
std::cout << "\nType patient's first name: ";
std::cin >> first_name;
std::cout << "\nType patient's second name: ";
std::cin >> second_name;
std::cout << "\nType patient's ID: ";
std::cin >> id;
std::cout << std::endl;
this->first_name_t = new char[std::strlen(first_name)];
std::strcpy(this->first_name_t, first_name);
delete first_name;
this->second_name_t = new char[std::strlen(second_name)];
std::strcpy(this->second_name_t, second_name);
delete second_name;
this->id_t = id;
}
patientType(const char* first_name, const char* second_name, const unsigned id)
{
this->first_name_t = new char[std::strlen(first_name)];
std::strcpy(this->first_name_t, first_name);
this->second_name_t = new char[std::strlen(second_name)];
std::strcpy(this->second_name_t, second_name);
this->id_t = (unsigned)id;
}
~patientType() //De
{
this->id_t = 0;
delete[] this->first_name_t;
delete[] this->second_name_t;
}
friend std::ostream& operator<<(std::ostream& os, patientType& patient)
{
os << patient.first_name() << std::left << std::setw(3) << ' ' << patient.second_name() << std::left << std::setw(3) << ' ' << patient.id() << std::endl;
return os;
}
void save(std::ofstream& ofs)
{
ofs << this->first_name() << "\t" << this->second_name() << "\t" << this->id() << "\n";
}
void save(std::fstream& ofs)
{
ofs << this->first_name() << "\t" << this->second_name() << "\t" << this->id() << "\n";
}
void operator=(const patientType& patient)
{
this->first_name_t = new char[std::strlen(patient.first_name_t)];
std::strcpy(this->first_name_t, patient.first_name_t);
this->second_name_t = new char[std::strlen(patient.second_name_t)];
std::strcpy(this->second_name_t, patient.second_name_t);
this->id_t = (unsigned)patient.id_t;
}
const char* first_name() {return const_cast<const char*>(this->first_name_t);}
const char* second_name() {return const_cast<const char*>(this->second_name_t);}
const unsigned id() {return (const unsigned)id_t;}
};
#include <vector>
template<class T> std::vector<unsigned> binary_search(T* var, T term, unsigned size)
{
std::vector<unsigned> ret;
unsigned mid = size / 2;
for(unsigned i = 0; i < mid; i++) {if(var[i] == term) ret.push_back(i);}
for(unsigned i = mid; i < size; i++) {if(var[i] == term) ret.push_back(i);}
return ret;
}
template<class T, class BinaryCompare> std::vector<unsigned> binary_search(T* var, T term, unsigned size, BinaryCompare compare_operation)
{
std::vector<unsigned> ret;
unsigned mid = size / 2;
for(unsigned i = 0; i < mid; i++) {if(compare_operation(var[i],term)) ret.push_back(i);}
for(unsigned i = mid; i < size; i++) {if(compare_operation(var[i],term)) ret.push_back(i);}
return ret;
}
template <typename T> void swap(T& var, T& var1)
{
T temp = var;
var = var1;
var1 = temp;
}
template <typename T> void selection_sort(T* var, unsigned size, unsigned pos = 0) //1 3 5 2 4; tamanho 5
{
if(!(pos >= size))
{
for(int i = pos+1; i < size; i++)
{
if(var[pos] > var[i]) swap(var[pos], var[i]);
}
selection_sort(var, size, pos+1);
}
else return;
}
template <typename T, typename BinaryCompare>void selection_sort(T* var, unsigned size, BinaryCompare compare_operation, unsigned pos = 0)
{
if(!(pos >= size))
{
for(int i = pos+1; i < size; i++)
{
if(compare_operation(var[pos], var[i])) swap(var[pos], var[i]);
}
selection_sort(var, size, compare_operation, pos+1);
}
else return;
}
So I did the main ():
#include <iostream>
#include <fstream>
#include "patientType.hpp"
#include "search.hpp"
#include "sort.hpp"
#include <string>
#include <sstream>
bool file_exists(const char* file)
{
std::ifstream file_(file);
if(!file_.good() || file_.fail() || file_.bad()) return false; else return true;
}
bool empty_file(const char* file)
{
std::ifstream file_(file);
return file_.peek() == std::ifstream::traits_type::eof();
}
int main()
{
while(true)
{
unsigned option = 0;
if(!file_exists("patient.db") || empty_file("patient.db"))
{
std::ofstream file("patient.db");
std::cout << "1. Add patient\n";
std::cout << "2. Exit\n> ";
std::cin >> option;
switch(option)
{
case 1:{patientType patient; patient.get(); patient.save(file); break;}
case 2: {exit(0);break;}
default: {std::cout << "Input a valid option.\n";break;}
}
}
else
{
std::string file_content;
std::fstream file("patient.db");
unsigned file_size = 0;
while(std::getline(file, file_content)) {if(!file_content.empty()) file_size++;}
file.close();
file.open("patient.db");
patientType* patients = new patientType[file_size];
int instance = 0;
while(std::getline(file, file_content))
{
std::string params[3];
std::stringstream A(file_content);
for(int i = 0; std::getline(A, file_content, '\t');) {if(!file_content.empty()){params[i] = file_content;i++;}}
patientType A_(params[0].c_str(), params[1].c_str(), std::stoi(params[2]));
patients[instance] = A_;
instance++;
}
std::cout << "1. Print patient\n2. Add a patient\n3. Sort patients by last name\n4. Sort patients by ID\n5. Search patient by last name\n6. Search patient by ID\n7. Exit the program\n> ";
std::cin >> option;
switch(option)
{
case 1:
{
unsigned index;
std::cout << "\nSelect index (in range 1 to " << file_size << ").\n> ";
std::cin>> index;
if(index < 1 || index > file_size)
{
exit(-1);
}
else std::cout <<"\n" << std::left << "1st name" << std::left << std::setw(3) << " 2nd name" << std::left << std::setw(3) << " ID\n" << patients[index - 1] << "\n";
break;
}
case 2:
{
file.close();
patientType patient;
patient.get();
std::ofstream file_("patient.db", std::ios::app);
patient.save(file_);
break;
}
case 3:
{
selection_sort(patients, file_size, [](patientType& first, patientType& second){return first.second_name() > second.second_name();});
break;
}
case 4:
{
selection_sort(patients, file_size, [](patientType& first, patientType& second){return first.id() > second.id();});
break;
}
case 5:
{
unsigned term;
std::cout << "Input the ID term: ";
std::cin >> term;
std::vector<unsigned> occurrences = binary_search(patients, patientType("","",term), file_size, [](patientType& first, patientType& second){return first.id() == second.id();});
std::cout << "Found " << occurrences.size() << " occurrences.\n";
for(auto a : occurrences)
{
std::cout << patients[a];
std::cout << "\nAt " << a << "\n";
}
std::cout << std::endl;
break;
}
case 6:
{
char* term = new char[128];
std::cout << "Input the last name term: ";
std::cin >> term;
std::vector<unsigned> occurrences = binary_search(patients, patientType("", term,0), file_size, [](patientType& first, patientType& second){return first.second_name() == second.second_name();});
std::cout << "Found " << occurrences.size() << " occurrences.\n";
for(auto a : occurrences)
{
std::cout << patients[a];
std::cout << "\nAt " << a << "\n";
}
std::cout << std::endl;
delete[] term;
break;
}
case 7:
{
exit(0);
}
}
}
}
}
If you test yourself, it goes into multiple functions, debug gives SIGTRAP
several times and out of nothing, when you ask for an input several times it crash - to . The program (with the requirements) would be slow, but probably would not bug. Where is the error? How to arrange?