Convert big dataset from .txt to .arff format - weka

I have big dataset about 1 GB that I need to convert from .txt to .arff format. All sources convert from .txt to .csv and then to .arff but with online converter the max size is 100 MB. Any one help me how to convert this 1 GB data?

You can convert txt file to csv with this snippet.
import java.io.*;
public class Convert {
public static void main(String[] args) {
System.out.println("Initialize ...");
Read read = new Read("soal01.txt");
Print print = new Print();
for (int i = 1; i <= 3; i++) {
try{
print.setFileName("jawaban"+i+".csv");
read.setPrint(print);
read.exec(i);
} catch(IOException ex){
ex.printStackTrace();
}
}
System.out.println("Finished");
}
}
class Print {
protected String fileName;
protected FileWriter writer;
public Print() {}
public Print(String fileName) throws IOException {
this.fileName = fileName;
this.writer = new FileWriter(this.fileName);
}
public String getFileName() {
return this.fileName;
}
public void setFileName(String fileName) throws IOException {
this.fileName = fileName;
this.writer = new FileWriter(this.fileName);
}
public void close() throws IOException {
this.writer.flush();
this.writer.close();
}
public void addRow(String[] c) throws IOException {
int l = c.length;
for(int i = 0; i < l; i++) {
this.writer.append(c[i]);
if(i != (l - 1)) {
this.writer.append(",");
}
}
this.writer.append('\n');
}
}
class Read {
protected String fileName;
protected BufferedReader bufferedReader;
protected Print print;
public Read(String fileName) {
this.fileName = fileName;
}
public Read(Print print, String fileName) {
this.print = print;
this.fileName = fileName;
}
public void setPrint(Print print) {
this.print = print;
}
public Print getPrint() {
return this.print;
}
public void exec(Integer type) {
String sCurrentLine = "";
try{
this.bufferedReader = new BufferedReader(
new FileReader(this.fileName));
while((sCurrentLine = this.bufferedReader.readLine()) != null) {
String[] columns = sCurrentLine.split("\t");
int length = columns.length;
if(type == 1) {
this.print.addRow(columns);
} else if(length >= 2){
double col1 = Double.parseDouble(columns[1]);
if(col1 > 20){
if(type == 2){
this.print.addRow(columns);
} else if(type == 3 && length >= 3 && columns[2] != null){
this.print.addRow(columns);
}
}
}
}
this.print.close();
} catch(IOException ex) {
ex.printStackTrace();
} finally {
try{
if(this.bufferedReader != null) {
this.bufferedReader.close();
}
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
}

Related

How to write optimized constructor in a class >

I wrote writing an email class, but I am not sure if this is the best way to write this... here's the code for it...
class email
{
string value;
string domain;
string com;
string username;
string encrypted;
bool state ;
public:
email(const string& val)
:value{ val}, state{false},com(),domain(),username(),encrypted()
{
for (int i = 0; i < value.size(); ++i)
{
if (value[i] == '#')
{
username = value.substr(0, i);
for (int j = i; j < value.size(); ++j)
{
if (value[j] == '.')
{
domain = value.substr(i, j);
com = value.substr(j+1, value.size()-1);
state = true;
}
}
}
}
if (state)
{
for (auto letter : value)
{
if (letter == ';' || letter == '\'' || letter == '[' || letter == ']')
{
state = false;
}
}
} else throw "invalid string";
if (state)
{
encrypted = username;
for (int i = 0; i < username.size() / 2; ++i)
{
swap(encrypted[i], encrypted[encrypted.size() - 1 - i]);
encrypted[i] = static_cast<char>(static_cast<int>(encrypted[i]) + 3);
}
}else throw "invalid charecters";
}
const string& get_domain() { return domain; }
const string& get_username() { return username; }
const string& get_com() { return com; }
const string& get_enc() { return encrypted; }
const bool good () const { return state; }
};
It's not completed yet, this is just a quick sketch from what I can remember because I don't have the actual code right now, my question is should I make another class to support the email class.. or is this the right way? I wrote a lot of code inside the constructor, that's what I am worried about.
You could break the for loops, if you have done your stuff.
First for: after you found '#' you do not have to loop to the end
Third for: after you found an error, you could throw immediatelly

munmap_chunk(): invalid pointer (core dumped)

Code actually runs fine for me, but I have to submit it to someone, and in return I get an error which I cannot perceive.
The following error is:
munmap_chunk(): invalid pointer (core dumped)
The error appears to be occurring in method named: loadLuggage. I have also checked the code with Valgrind, but no possible leaks were detected. Perhaps I was not compiling it correctly.
#include <iostream>
#include <string>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;
template<typename T>
int izbrisiVrsto(queue<T> &queue) {
int numberOfRemoved = 0;
while (!queue.empty()) {
queue.pop();
numberOfRemoved++;
}
return numberOfRemoved;
}
template<typename T>
int deleteStack(stack<T> &stack) {
int numberOfDeleted = 0;
while (!stack.empty()) {
stack.pop();
numberOfDeleted++;
}
return numberOfDeleted;
}
class Traveler {
private:
string name;
string surname;
int age;
string emso; //used as ID
public:
Traveler(const string &name, const string &surname, int age, const string &emso)
: name(name), surname(surname), age(age), emso(emso) {
}
~Traveler() {}
string getName() const {
return name;
}
void setName(const string &name) {
this->name = name;
}
string getSurname() const {
return surname;
}
void setSurname(const string &surname) {
this->surname = surname;
}
int getAge() const {
return age;
}
void setAge(int age) {
this->age = age;
}
string getEmso() const {
return emso;
}
void setEmso(const string &emso) {
this->emso = emso;
}
};
enum TravelClass {
ECONOMY,
BUSINESS
};
class Luggage {
private:
int luggageID;
public:
Luggage(int id) : luggageID(id) {}
~Luggage() {}
int getLuggageID() const {
return luggageID;
}
void setLuggageID(int id) {
this->luggageID = id;
}
};
class BoardingTicket {
private:
Traveler traveler;
TravelClass travelClass;
Luggage luggage;
public:
BoardingTicket(const Traveler &traveler, const TravelClass &pr, const Luggage &luggage)
: traveler(traveler), travelClass(pr), luggage(luggage) {
}
~BoardingTicket() {}
Traveler getTraveler() const {
return traveler;
}
void setTraveler(const Traveler &traveler) {
this->traveler = traveler;
}
TravelClass getTravelClass() const {
return travelClass;
}
void setTravelClass(TravelClass travelClass) {
this->travelClass = travelClass;
}
Luggage getLuggage() const {
return luggage;
}
void setLuggage(const Luggage &luggage) {
this->luggage = luggage;
}
};
class Plane {
private:
int id; //plane ID
public:
stack<stack<Luggage> > trunk; //stack of luggage on plane = all travelers luggage
private:
unsigned int maxNumberOfLuggage; //number of maxium luggage on the heap
public:
Plane(int id, unsigned int maxNumberOfLuggage) :
id(id),
maxNumberOfLuggage(maxNumberOfLuggage) {
}
~Plane() {}
//get/set metode
int getID() const {
return id;
}
void setID(int id) {
this->id = id;
}
unsigned int getMaxNumberOfLuggage() const {
return maxNumberOfLuggage;
}
void setMaxNumberOfLuggage(unsigned int maxNumberOfLuggage) {
this->maxNumberOfLuggage = maxNumberOfLuggage;
}
void loadLuggage(queue<Luggage> &luggages) {
//TODO: implementation
while (luggages.empty() == false) {
stack<Luggage> pallet; //certain number of luggage on pallet
for (int i = 0; i < this->maxNumberOfLuggage; i++) {
Luggage luggage = luggages.front();
pallet.push(luggage);
luggages.pop();
}
this->trunk.push(pallet); //loading in trunk
}
}
queue<Luggage> unloadLuggage() {
//TODO: implementation
queue<Luggage> unloadingLuggage;
while (trunk.empty() == false) {
stack<Luggage> pallet = trunk.top();
trunk.pop();
for (int i = 0; i < pallet.size(); i++) {
unloadingLuggage.push(pallet.top());
pallet.pop();
}
}
return unloadingLuggage; //HACK: dummy return
}
};
class Airline {
public:
queue<BoardingTicket> boardingPeople; //people waiting to board on a plane
queue<Luggage> unloadedLuggage;
Airline() {}
~Airline() {}
void split(queue<BoardingTicket> &travelers, queue<BoardingTicket> &businessTravelers,
queue<BoardingTicket> &economyTravelers) {
//TODO: implementation
while (travelers.empty() == false) {
BoardingTicket traveler = travelers.front(); //izbira prvega potnika
if (traveler.getTravelClass() == ECONOMY) {
economyTravelers.push(traveler);
} else if (traveler.getTravelClass() == BUSINESS) {
businessTravelers.push(traveler);
}
travelers.pop(); //traveler vkrcan
}
}
queue<BoardingTicket> merge(queue<BoardingTicket> &businessTravelers, queue<BoardingTicket> &economyTravelers) {
//TODO: implementation
queue<BoardingTicket> merged;
while (economyTravelers.empty() == false) {
BoardingTicket first = economyTravelers.front();
merged.push(first);
economyTravelers.pop();
}
while (businessTravelers.empty() == false) {
BoardingTicket first = businessTravelers.front();
merged.push(first);
businessTravelers.pop();
}
return merged; //HACK: dummy return
return queue<BoardingTicket>(); //HACK: dummy return
}
queue<BoardingTicket> edit(queue<BoardingTicket> &waitingQueue) {
queue<BoardingTicket> businessTravelers;
queue<BoardingTicket> economyTravelers;
split(waitingQueue, businessTravelers, economyTravelers);
return merge(businessTravelers, economyTravelers);
}
void opravilaPriLetu(queue<BoardingTicket> readyPassengers,
queue<Luggage> appliedLuggage,
Plane lt) {
if (boardingPeople.size() != 0)
izbrisiVrsto(boardingPeople);
if (unloadedLuggage.size() != 0)
izbrisiVrsto(unloadedLuggage);
boardingPeople = edit(readyPassengers);
lt.loadLuggage(appliedLuggage);
//flying to destination
unloadedLuggage = lt.unloadLuggage();
}
};
bool MergeExclusivelyInBusinessClass() {
queue<BoardingTicket> business;
int luggageID = 0;
Traveler pt1("Victor", "Candice", 25, "1111111111111");
TravelClass pr1 = BUSINESS;
Luggage k1(luggageID++);
BoardingTicket kzv1(pt1, pr1, k1);
business.push(kzv1);
Traveler pt2("Charles", "Sennet", 17, "1111111111112");
TravelClass pr2 = BUSINESS;
Luggage k2(luggageID++);
BoardingTicket kzv2(pt2, pr2, k2);
business.push(kzv2);
Traveler pt3("Marc", "Cooper", 18, "1111111111113");
TravelClass pr3 = BUSINESS;
Luggage k3(luggageID++);
BoardingTicket kzv3(pt3, pr3, k3);
business.push(kzv3);
Traveler pt4("Frank", "McLorre", 45, "1111111111114");
TravelClass pr4 = BUSINESS;
Luggage k4(luggageID++);
BoardingTicket kzv4(pt4, pr4, k4);
business.push(kzv4);
queue<BoardingTicket> economy;
queue<BoardingTicket> mergeExpected = business;
Airline ld;
queue<BoardingTicket> actuallyMerged = ld.merge(business, economy);
if (mergeExpected.size() != actuallyMerged.size()) {
cout << "Metoda merge() did not fulfill did not fullfill with correct number of passenger ("
<< (int) mergeExpected.size() << "), but with " << (int) actuallyMerged.size() << " travelers." << endl;
return false;
}
while (!mergeExpected.empty() && !actuallyMerged.empty()) {
BoardingTicket actual = actuallyMerged.front();
actuallyMerged.pop();
BoardingTicket expected = mergeExpected.front();
mergeExpected.pop();
Traveler expectedP = expected.getTraveler();
Traveler actualP = actual.getTraveler();
TravelClass expectedPR = expected.getTravelClass();
TravelClass actualyPR = actual.getTravelClass();
Luggage expectedK = expected.getLuggage();
Luggage actualyK = actual.getLuggage();
if (expectedP.getEmso() != actualP.getEmso() || expectedP.getAge() != actualP.getAge() ||
expectedP.getSurname() !=
actualP.getSurname() ||
expectedP.getName() !=
actualP.getName() || expectedPR != actualyPR ||
expectedK.getLuggageID() !=
actualyK.getLuggageID()) {
cout << "Metoda merge() did not fill up expected queue of merged travelers with travelers that were given."
<< endl;
return false;
}
}
return true;
}
int main(int argn, char **args) {
if (MergeExclusivelyInBusinessClass())
cout << "Method merge() is successful." << endl;
else
cout << "Method merge() failed." << endl;
return 0;
}
I have troubles comprehending an error, and I'm not really sure how to solve it. Any ideas?
EDIT 1
I have been notified that error could be caused by for loop itself, because queue/stack size is constantly changing, therefore it is recommended to use while loop instead.
EDIT 2
I have finally managed to discover where exactly the problems appear:
Errors_Image
Without any further information about the error, its probable the invalid pointer error is occurring in the for-loop of the loadLuggage function. The first line of the for-loop accesses the front element of the luggages queue without checking if the queue is empty. Therefore, if the variable "maxNumberOfLuggage" has been set to a value that is greater than the size of the queue, you will get an invalid pointer error. Try modifying the for-loop to:
for (int i = 0; i < this->maxNumberOfLuggage; i++) {
Luggage luggage = luggages.front();
pallet.push(luggage);
luggages.pop();
if(luggages.empty()) break; //add this line of code
}
This may solve your problem.
If not, please provide more information on the error.

Virtual function not overloading in derived class [duplicate]

This question already has answers here:
What is object slicing?
(18 answers)
Closed 2 years ago.
class CommandRoot {
protected:
string cmdString = "";
string title = "";
string tags = "";
string description = "";
public:
string getCmdString() {
return cmdString;
}
string getTitle() {
return title;
}
string getTags() {
return tags;
}
string getDescription() {
return description;
}
virtual bool onTrigger() {
return 1;
}
};
class CmdFirst : public CommandRoot{
public:
CmdFirst() {
cmdString = "testing1";
title = "";
tags = "";
description = "";
}
bool onTrigger() {
cout << "C";
return 0;
}
};
class Player {
NPC *target = NULL;
CommandRoot *cmdList[1];
public:
Player() {
cmdList[0] = new CmdFirst();
}
CommandRoot getCmdList(int n) {
return *cmdList[n];
}
NPC getTarget() {
return *target;
}
bool setTarget(NPC* t) {
target = t;
return 0;
}
string listen() {
string cmd = "";
cin >> cmd;
return cmd;
}
};
int main()
{
std::cout << "Hello World!\n";
Player* player = new Player();
NPC* firstNPC = new NPC();
player->setTarget(firstNPC);
bool exit = false;
do {
if (player->listen().compare(player->getCmdList(0).getCmdString()) == 0) {
cout << "A";
cout << player->getCmdList(0).onTrigger();
}
else
{
cout << "B";
}
} while (exit == false);
}
The following line is calling the parent's virtual function instead of the derived class.
cout << player->getCmdList(0).onTrigger();
I have a feeling it's because the data type of the array is the parent class, but that shouldn't prevent the array element from being assigned the data type of the derived class, then calling that class's function.
It's because CommandRoot getCmdList(int n) returns a CommandRoot object. For virtual functions to work you need a reference or a pointer.
Try changing to
CommandRoot& getCmdList(int n) {
return *cmdList[n];
}

How to initialize an object once and use it for all test cases

I have a test class where I have all my test cases for my java project, I want to initialize the service class once which creates an array and I want to use the same array for all the other test cases, I have tried to do that but when the first test case is ran an customer is registered and stored in the array I want to use the customer stored in the array and use it for the next test case but it seems that the customer is not in the array for the next test case i.e a new array is being created or I think that junit is running each test case individually
MainTests.java
package tests;
import static org.junit.Assert.*;
import org.junit.*;
import services.BankingServiceImpl;
import dao.BankingSystemArrayImpl;
public class MainTests {
static BankingServiceImpl bankingService;
private static boolean setupIsDone = false;
#BeforeClass
public static void setup() {
bankingService = new BankingServiceImpl();
}
#Test // 1
public void createCustomer() {
String custName = "Rohan";
String HomeAddressCity = "Pune";
String HomeAddressState = "Maharashtra";
int HomeAddressPincode = 411043;
String LocalAddressCity = "Pune";
String LocalAddressState = "Pune";
int LocalAddressPincode = 411043;
int day = 19;
int month = 9;
int year = 1998;
int result = bankingService.acceptCustomerDetails(custName, HomeAddressCity, HomeAddressState,
HomeAddressPincode, LocalAddressCity, LocalAddressState, LocalAddressPincode, day, month, year);
System.out.println(bankingService.getLength());
assertTrue(result > 0);
}
#Test // 2
public void openCustomerAccount() {
System.out.print(bankingService.getLength());
int customerid = 100;
int balance = 100000;
String accountType = "savings";
int result = bankingService.openAccount(customerid, balance, accountType);
assertTrue(result > 0);
}
#Test // 3
public void Balance() {
int customerid = 100;
int accountid = 50;
int pin = 1007;
int result = bankingService.getAccountBalance(customerid, accountid, pin);
assertTrue(result > 0);
}
#Test // 4
public void amt_withdraw() {
int customerid = 100;
int accountid = 50;
int amount = 10000;
int pin = 1007;
int result = bankingService.withdraw(customerid, accountid, amount, pin);
assertEquals(result, 90000);
}
#Test // 5
public void transfer() {
int customerid = 100;
int accountid = 50;
int customerid1 = 101;
int accountid1 = 51;
int amount = 10000;
int pin = 1007;
boolean result = bankingService.fundTransfer(customerid, accountid, customerid1, accountid1, amount, pin);
assertEquals(result, true);
}
#Test // 6
public void amt_deposit() {
int customerid = 100;
int accountid = 50;
int amount = 10000;
int result = bankingService.deposit(customerid, accountid, amount);
assertEquals(result, 90000);
}
/*
* #Test //7 public void cust_details() { int customerid = 100;
* BankingServiceImpl bankingService = new BankingServiceImpl();
*
* int result = bankingService.getCustomerDetails(customerid);
* assertEquals(result, 90000); }
*/
#Test // 10
public void pin_change() {
int customerid = 100;
int accountid = 50;
int o_pin = 1007;
int n_pin = 1122;
boolean result = bankingService.changePin(customerid, accountid, o_pin, n_pin);
assertEquals(result, true);
}
#Test // 11
public void check_change() {
int customerid = 100;
int accountid = 50;
int pin = 1007;
boolean result = bankingService.checkPin(customerid, accountid, pin);
assertEquals(result, true);
}
}
Service Class
package services;
import beans.Account;
import beans.Address;
import beans.Customer;
import beans.MyDate;
import beans.Transaction;
import dao.BankingSystemArrayImpl;
public class BankingServiceImpl {
BankingSystemArrayImpl BankingSystemArray;
public BankingServiceImpl() {
System.out.print("called");
BankingSystemArray = new BankingSystemArrayImpl();
}
/*
* public void transfer(int accountId, int tansferAccountId, double amount)
* { double a = BankingSystemArray.getAccount(accountId).getBalance()
* - amount; System.out.println(a);
* BankingSystemArray.getAccount(accountId).setBalance(a); double b =
* BankingSystemArray.getAccount(accountId).getBalance() + amount;
* BankingSystemArray.getAccount(tansferAccountId).setBalance(b);
*
* }
*/
public int acceptCustomerDetails(String custName, String HomeAddressCity,
String HomeAddressState, int HomeAddressPincode,
String LocalAddressCity, String LocalAddressState,
int LocalAddressPincode, int day, int month, int year) {
if ((day > 0 && day <= 31) && (month >= 1 && month <= 12)
&& (year <= 2015)) {
return BankingSystemArray.insertCustomer(new Customer(
custName, new Address(LocalAddressCity, LocalAddressState,
LocalAddressPincode), new Address(HomeAddressCity,
HomeAddressState, HomeAddressPincode), new MyDate(
day, month, year)));
} else
return 0;
}
public int openAccount(int custId, int balance, String accType) {
int accountId = 0;
if (custId < 99) {
System.out
.println("Invalid customer Id,please enter a valid customer Id");
} else if (!(accType.equalsIgnoreCase("savings")
|| accType.equalsIgnoreCase("current") || accType
.equalsIgnoreCase("salary"))) {
System.out
.println("Invalid account type, please enter a valid account type");
} else if (balance < 0) {
System.out.println("Invalid amount, please amount a valid amount");
}
else {
Customer customer = BankingSystemArray.getCustomer(custId);
if (customer == null) {
System.out.println("Sorry you have not registered");
return 0;
} else {
Account account = new Account(accType, balance);
accountId = BankingSystemArray.insertAccount(account,
custId);
}
}
return accountId;
}
public int getAccountBalance(int custId, int accNo, int pin) {
if (checkPin(custId, accNo, pin)) {
return BankingSystemArray.getAccount(custId, accNo)
.getBalance();
} else {
System.out.println("Invalid pin");
return 0;
}
}
public int withdraw(int custId, int accNo, int amt, int pin) {
int balance = 0;
if (amt < 0) {
System.out.println("Invalid amount, please enter a valid amount");
} else {
Customer customer = BankingSystemArray.getCustomer(custId);
if (customer == null) {
return 0;
} else {
Account account = BankingSystemArray.getAccount(custId,
accNo);
if (account == null) {
System.out.println("Sorry your account does not exist");
} else if (account.getPin()!=pin) {
System.out.println("Invalid pin");
return 0;
} else {
if ((account.getBalance() - amt) > 0) {
account.setBalance(account.getBalance() - amt);
balance = account.getBalance();
}
}
}
}
return balance;
}
public boolean fundTransfer(int custIdFrom, int accNoFrom, int custIdTo,
int accNoTo, int amt, int pin) {
if (withdraw(custIdFrom, accNoFrom, amt, pin) > 0) {
deposit(custIdTo, accNoTo, amt);
return true;
}
return false;
}
public int deposit(int custId, int accNo, int amt) {
if (amt < 0) {
System.out.println("Invalid amount, please enter a valid amount");
} else {
BankingSystemArray.getAccount(custId, accNo).setBalance(
BankingSystemArray.getAccount(custId, accNo)
.getBalance() + amt);
return BankingSystemArray.getAccount(custId, accNo)
.getBalance();
}
return 0;
}
public Customer getCustomerDetails(int custId) {
Customer customer = BankingSystemArray.getCustomer(custId);
if (customer != null) {
return customer;
}
return null;
}
public Account getAccountDetails(int custId, int accNo) {
Account account = BankingSystemArray.getAccount(custId, accNo);
if (account != null) {
return account;
}
return null;
}
public Account[] getAllAccountsDetails(int custId) {
Account[] account = BankingSystemArray.getAccountList(custId);
if (account != null) {
return account;
}
return null;
}
public Transaction[] getAllTransactionDetails(int custId, int accNo) {
// TODO Auto-generated method stub
return null;
}
public int generatePin(int custId, int accNo) {
Account account = BankingSystemArray.getAccount(custId, accNo);
int pin = BankingSystemArray.generateRandomNumber();
account.setPin(pin);
return account.getPin();
}
public boolean changePin(int custId, int accNo, int oldPin, int newPin) {
Account account = BankingSystemArray.getAccount(custId, accNo);
if (account != null) {
if (account.getPin() == oldPin) {
account.setPin(newPin);
return true;
}
}
return false;
}
public boolean checkPin(int custId, int accNo, int pin) {
Account account = BankingSystemArray.getAccount(custId, accNo);
if (account != null) {
if (account.getPin() == pin) {
return true;
}
}
return false;
}
public Customer getLength() {
return BankingSystemArray.getLength();
}
}
To solve your problem, you need first to understand the JUnit behavior.
Methods marked with #BeforeClass and #AfterClass are run only
once, and are the upper and lower bound of all your test methods.
Methods marked with #Before and #After are run immediately
before and after any test method.
Only static members are shared between test cases. So all instance
members are being reset before any test method.
Also note that as a RULE in Unit Testing, all tests (all test methods) MUST be isolated from each other, but it's OK in integration testing.

Members of child class are empty (polymorphism)

I have the following problem:
I have main executable program called algatorc. In this program, I have class called TestCase, AbsAlgorithm and TestSetIterator. End user must create new algatorc program and then inherits these three classes.
Let's say that end user creates project Sorting. He would end up with three classes called SortingTestCase, SortingTestSetIterator and SortingAbsAlgorithm.
So here is the thing. End user has a method SortingTestSetIterator::get_current and return type of this function is TestCase*. In this method, he creates instance of SortingTestCase and return this instance. So he actually returned child of TestCase. In my main program I save this pointer to TestCase *t (and no, I can't save it as SortingTestCase, because before runtime, I don't know the name of the project) and then I send this pointer to method SortingAbsAlgorithm::init(TestCase* test_case). In this particulary method, end user will probably cast this object to his (SortingTestCase), and this is done like this:
sorting_test_case = dynamic_cast<SortingTestCase*>(test);
This SortingTestCase is derived from TestCase and has all members from parent class and two variables of his own: array and size. So when in init method I say
for (int i = 0; i<sorting_test_case->size; i++)
{
std::cout << sorting_test_case[i] << std::endl;
}
then I get nothing. It seems like array is empty.
Any idea what am I doing wrong?
Edit:
class SortingAbsAlgorithm : public AbsAlgorithm
{
private:
SortingTestCase *sorting_test_case;
public:
bool init (TestCase *test)
{
sorting_test_case = dynamic_cast<SortingTestCase*>(test);
std::cout << "INIT ARRAY" << std::endl;
for (int i = 0; i<sorting_test_case->size; i++)
{
std::cout << sorting_test_case->array_to_sort[i] << " ";
}
}
};
class SortingTestCase : public TestCase
{
public:
int size;
int *array_to_sort;
void init_array(int tab[], int size)
{
array_to_sort = new int[size];
for (int i = 0; i<size; i++)
{
array_to_sort[i] = tab[i];
}
}
};
class SortingTestSetIterator : public TestSetIterator
{
private:
std::string file_path;
std::string test_file_name;
public:
TestCase *get_current()
{
if (current_input_line.empty())
{
return nullptr;
}
std::vector<std::string> fields;
std::string token;
std::stringstream str(current_input_line);
while ( getline(str, token, ':') )
{
fields.push_back(token);
}
str.clear();
if (fields.size() < 3)
{
report_invalid_data_format("to few fields");
return nullptr;
}
std::string test_name = fields.at(0);
int prob_size;
try
{
prob_size = std::atoi(fields.at(1).c_str());
} catch (...)
{
report_invalid_data_format("'n' is ot a number");
}
std::string group = fields.at(2);
std::string test_id = "Test-" + std::to_string(line_number);
EParameter *test_id_par = new EParameter("TestID", "Test identificator", test_id);
EParameter *parameter1 = new EParameter("Test", "Test name", test_name);
EParameter *parameter2 = new EParameter("N", "Number of elements", std::to_string(prob_size));
EParameter *parameter3 = new EParameter("Group", "A name of a group of tests", group);
SortingTestCase *t_case = new SortingTestCase();
t_case->addParameter(*test_id_par);
t_case->addParameter(*parameter1);
t_case->addParameter(*parameter2);
t_case->addParameter(*parameter3);
int arr[prob_size];
int i = 0;
if (group == "INLINE")
{
if (fields.size() < 4)
{
report_invalid_data_format("to few fields");
return nullptr;
}
std::vector<std::string> data;
std::stringstream ss(fields.at(3));
while (getline(ss, token, ' ') )
{
data.push_back(token);
}
if (data.size() != prob_size)
{
report_invalid_data_format("invalid number of inline data");
return nullptr;
}
try
{
for (i = 0; i<prob_size; i++)
{
arr[i] = std::atoi(data.at(i).c_str());
}
} catch (...)
{
report_invalid_data_format("invalid type of inline data - data " + std::to_string((i+1)));
return nullptr;
}
}
else if (group == "RND")
{
srand(time(NULL));
for (i = 0; i<prob_size; i++)
{
arr[i] = rand() % prob_size + 1000;
}
}
else if (group == "SORTED")
{
for (i = 0; i<prob_size; i++)
{
arr[i] = i;
}
}
else if (group == "INVERSED")
{
for (i = 0; i<prob_size; i++)
{
arr[i] = prob_size - i;
}
}
t_case->init_array(arr, prob_size);
return t_case;
}
};
This are end users classes. I create library out of this classes and I load them in my program via dlopen and dlsym. I get instance of classes like this:
#ifdef __cplusplus
extern "C" {
#endif
TestSetIterator * create_iterator_object() {
return new SortingTestSetIterator;
}
void destroy_iterator_object(TestSetIterator* object) {
delete object;
}
#ifdef __cplusplus
}
and then in my main program I load symbol create_iterator_object
create_it = (TestSetIterator* (*)())dlsym(handle, "create_iterator_object");
and then I say this:
TestSetIterator *it = (TestSetIterator*)create_it();
I can call it->get_current() which loads line from file to variable curent_input_line. So I do this:
TestCase *t_case = it->get_current();
and then I say
a->init(t_case)
a is here actually SortingAbsAlgorithm loaded exactly the same as TestSetIterator (ofcourse, different symbol) and is "saved" into AbsAlgorithm a*.
So when a->init(t_case) is called, then in this init end-user cast t_case this is type of TestCase to SortingTestCase. And when I want to print elements in array, array is empty.