My task would be to make this object hierarchy and have a sum of all file sizes in the file system.
If I understand correctly this would be a multi level inheritance, but I'm not sure how to write a function what can run through every lower-level object and sum them up.
#include <iostream>
using namespace std;
class File{
public:
//File(int x){filesize=x;}
void setSize(int x){filesize=x;}
void showsize(){cout<<filesize<<endl;}
int getsize(){return filesize;}
private:
int filesize;
};
class Directory : public File {
public:
void SumDir(){
}
private:
int sumofdir=0;
};
int main()
{
File b;
b.setSize(416);
b.showsize();
return 0;
}
You could have the Directory class have a std::vector of File*. Then it would be just a simple walkthrough of each of these directory entries and in turn, invoke the getSize() on them. getSize() could be a polymorphic function that just either gets the size of the File if it's a regular file or the size of the entire directory if it's an instance of a Directory. Something on these lines:
#include <iostream>
#include <vector>
class File{
public:
explicit File(int x): fileSize(x){}
void setSize(int x){
fileSize=x;
}
void showSize() const{
std::cout<<fileSize<<'\n';
}
virtual size_t getSize() const{
return fileSize;
}
virtual ~File() = default;
private:
int fileSize;
};
class Directory : public File {
public:
Directory() : File(0){} //Directory is just a File of 0 size
size_t getSize() const override{
size_t size = 0;
for(auto const& file: dirEntries) {
size += file->getSize();
}
return size;
}
void addFile(File* file) {
if(file != nullptr) {
dirEntries.push_back(file);
}
}
private:
std::vector<File*> dirEntries;
};
int main() {
Directory child;
File f1{10}, f2{20};
child.addFile(&f1);
child.addFile(&f2);
Directory parent;
File f3{30};
parent.addFile(&f3);
parent.addFile(&child);
std::cout<<parent.getSize(); //60
}
Related
So I recently started with C at exercism page.
I currently facing a rather simple challenge.
Determine if a word or phrase is an isogram.
An isogram (also known as a "non-pattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times.
Examples of isograms:
lumberjacks
background
downstream
six-year-old
The word isograms, however, is not an isogram, because the s repeats.
There are 15 tests in total, of which one specific is not passed:
test_isogram_with_duplicated_hyphen
I guess test number 15 also passes because of some error I don't see
Here's the testing code:
#include "test-framework/unity.h"
#include "isogram.h"
#include <stdlib.h>
void setUp(void)
{
}
void tearDown(void)
{
}
static void test_empty_string(void)
{
TEST_ASSERT_TRUE(is_isogram(""));
}
static void test_null(void)
{
TEST_IGNORE(); // delete this line to run test
TEST_ASSERT_FALSE(is_isogram(NULL));
}
static void test_isogram_with_only_lower_case_characters(void)
{
TEST_IGNORE();
TEST_ASSERT_TRUE(is_isogram("isogram"));
}
static void test_word_with_one_duplicated_character(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("eleven"));
}
static void test_word_with_one_duplicated_character_from_end_of_alphabet(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("zzyzx"));
}
static void test_longest_reported_english_isogram(void)
{
TEST_IGNORE();
TEST_ASSERT_TRUE(is_isogram("subdermatoglyphic"));
}
static void test_word_with_duplicated_letter_in_mixed_case(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("Alphabet"));
}
static void test_word_with_duplicated_letter_in_mixed_case_lowercase_first(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("alphAbet"));
}
static void test_hypothetical_isogrammic_word_with_hyphen(void)
{
TEST_IGNORE();
TEST_ASSERT_TRUE(is_isogram("thumbscrew-japingly"));
}
static void
test_hypothetical_word_with_duplicated_character_following_hyphen(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("thumbscrew-jappingly"));
}
static void test_isogram_with_duplicated_hyphen(void)
{
TEST_IGNORE();
TEST_ASSERT_TRUE(is_isogram("six-year-old"));
}
static void test_made_up_name_that_is_an_isogram(void)
{
TEST_IGNORE();
TEST_ASSERT_TRUE(is_isogram("Emily Jung Schwartzkopf"));
}
static void test_duplicated_character_in_the_middle(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("accentor"));
}
static void test_same_first_and_last_characters(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("angola"));
}
static void test_word_with_duplicated_character_and_with_two_hyphens(void)
{
TEST_IGNORE();
TEST_ASSERT_FALSE(is_isogram("up-to-date"));
}
int main(void)
{
UnityBegin("test_isogram.c");
RUN_TEST(test_empty_string);
RUN_TEST(test_null);
RUN_TEST(test_isogram_with_only_lower_case_characters);
RUN_TEST(test_word_with_one_duplicated_character);
RUN_TEST(test_word_with_one_duplicated_character_from_end_of_alphabet);
RUN_TEST(test_longest_reported_english_isogram);
RUN_TEST(test_word_with_duplicated_letter_in_mixed_case);
RUN_TEST(test_word_with_duplicated_letter_in_mixed_case_lowercase_first);
RUN_TEST(test_hypothetical_isogrammic_word_with_hyphen);
RUN_TEST(test_hypothetical_word_with_duplicated_character_following_hyphen);
RUN_TEST(test_isogram_with_duplicated_hyphen);
RUN_TEST(test_made_up_name_that_is_an_isogram);
RUN_TEST(test_duplicated_character_in_the_middle);
RUN_TEST(test_same_first_and_last_characters);
RUN_TEST(test_word_with_duplicated_character_and_with_two_hyphens);
return UnityEnd();
}
This is my code:
#include "isogram.h"
#include <stdlib.h>
#include <stdio.h>
/* gives new char array from input, only small letters */
char* clean_words(char* ptr_input)
{
// new container; everything bigger than 27 is impossible to be an isogram
static char cleaned[27] = {"00000000000000000000000000"};
int i = 0, j = 0, k = 0;
for (int i = 0; ptr_input[i] != '\000'; i++)
{
k++;
}
for (i=0; i <= k; i++, j++)
{
if (ptr_input[i] > 64 && ptr_input[i] < 91)
{
cleaned[j] = ptr_input[i] + 32;
}
else if (ptr_input[i] > 96 && ptr_input[i] < 123)
{
cleaned[j] = ptr_input[i];
}
else
{
j--;
}
}
char* ptr_output = &cleaned[0];
return ptr_output;
}
bool is_isogram(char phrase[])
{
if(phrase == NULL)
{ return false; }
char* ptr_a = clean_words(phrase);
char ca_empty[27] = {"00000000000000000000000000"};
for(int i = 0; i <= 27; i++, ptr_a++){
// first element is always copied
if(i == 0){
ca_empty[i] = *ptr_a;
continue;
}
// '0' is sentinel, meaning the input word is finished => exit loop.
if(*ptr_a == '0' || *ptr_a == '\000')
{ break; }
// following elements only copied if different than current input char
int j = 0;
// loop copied for doubles, exit when found
for(;j<i;j++)
{
if(ca_empty[j] == *ptr_a){
return false;
}
}
// if none was found, copy new letter
ca_empty[i] = *ptr_a;
}
return true;
}
So basically I solve this in 2 steps. First, I will reduce any input to small letters only. Second, I copy letter by letter to a new container and test doubles before every copy process.
Yes, there are certainly fancier solutions, but I'd like to know if anyone can spot why I get FAILED on "six-year-old". Especially, when it is working locally. Thanks! :-)
So I figured it out by myself:
The problem is the helper function clean_words.
The char array cleaned is declared as static. That means it will keep its value even after the current block is finished.
When the tests run through, cleaned will still contain remaining letters of the input from other tests. The solution would be removing the static keywird or implementing a way to clean up the container, like
memset(cleaned, '0', 26);
From https://en.cppreference.com/w/c/language/storage_duration
static storage duration.
The storage duration is the entire execution of the program, and the value stored in the object is initialized only once, prior to main function. All objects declared static and all objects with either internal or external linkage that aren't declared _Thread_local (since C11) have this storage duration.
This code compiles but crashes instantly. I've only tried it on devcppPortable. I am trying to make a class that can store a lot of complex data (i.e. an object that has multiple property sets and each set carries multiple figures).
Each object created would have a unique number of property sets and internal property values. I would like to be able to shape the class upon declaration so as not to allocate a bunch of unused space. Is something like this even possible?
#include<iostream>
using namespace std;
class a
{
public:
int amount;
struct b
{
int max;
int* prop;
b() {}
void set(int&);
~b(){delete prop;}
};
b* property;
a(int amt, int max0, int max1=0, int max2=0);
~a(){delete property;}
};
int main()
{
a object(2, 3, 5);
return 0;
}
a::a(int amt, int max0, int max1, int max2)
{
amount = amt;
property = new b[amt];
switch(amt)
{
case 3:
property[2].set(max2);
case 2:
property[1].set(max1);
case 1:
property[0].set(max0);
}
}
void a::b::set(int& m) {max = m; prop = new int[max];}
You allocate property with new[] but deleting it with delete, not delete[]
I am running my code and getting a segmentation fault in my Input_buf() even though i don't have a Input_buf function.Now the header where i have declared Input_buf is:
#ifndef __GLOBAL_H
#define __GLOBAL_H
#include <stdio.h>
#ifdef ALLOC
# define CLASS
# define I(x) x
#else
# define CLASS extern
# define I(x)
#endif
#define MAXINP 2048
CLASS int Verbose I(=0);
CLASS int No_lines I(=0);
CLASS int Unix I(=0);
CLASS int Public I(=0);
CLASS char *Template I(="lex.par");
CLASS int Actual_lineno I(=1);
CLASS int Lineno I(=1);
CLASS char Input_buf[MAXINP]; //line buffer for input
CLASS char *Input_file_name; //Input file name
CLASS FILE *Ifile; //Input Stream
CLASS FILE *ofile; //Output Stream
#endif
But i have no such function as Input_buf in any of the .c files i have linked.I used gdb to point out where the segment occurs and it shows Input_buf().But Input_buf() is used in this file first:
PRIVATE head(int suppress_output)
{
int transparent=0;
if(!suppress_output && Public)
fputs("#define YYPRIVATE\n\n",Ofile);
if(!No_lines)
fprintf(Ofile,"#line 1\"%s\"\n",Input_file_name);
while(fgets(Input_buf,MAXINP,Ifile))
{
++Actual_lineno;
if(!transparent)
strip_comments(&Input_buf);
if(Verbose>1)
printf("h%d: %s",Actual_lineno,Input_buf);
if(Input_buf[0]=='%')
{
if(Input_buf[1]=='%')
{
if(!suppress_output)
fputs("\n",Ofile);
break;
}
else
{
if(Input_buf[1]=='(')
transparent=1;
else if(Input_buf[1]==')')
transparent=0;
else
lerror(0,"ignoring illegal %%%c direct ( vv \n",Input_buf[1]);
}
}
else if(transparent || isspace(Input_buf[0]))
{
if(!suppress_output)
fputs(Input_buf,Ofile);
}
else
{
new_macro(Input_buf);
if(!suppress_output)
fputs("\n",Ofile);
}
}
}
Fruit.h
class Fruit
{
private:
std::int no[3];
public:
void initialize();
int print_type();
};
Fruit.cpp
#include "Fruit.h"
void Fruit::initialize() {
int no[] = {1, 2, 3};
}
int Fruit::print_type() {
return type[0];
}
Main.cpp
#include <iostream>
#include "Fruit.h"
using namespace std;
int main()
{
Fruit ff;
ff.initialize();
int output = ff.print_type();
cout << output;
system("pause");
return 0;
}
Assume the required directives are included inside all the files.
At this moment, I find a problem when getting back the ouput since it will not result in "0" but a garbage value. How can I fix it without using constructor?
Sincerely hope that someone would do me a favor.
This is the way that doesn't use constructors and destructors, I hope you find it useful.
#include <iostream>
class Fruit
{
private : int* no;
public : void initialize();
public : void clean();
public : int print_type();
};
void Fruit::initialize()
{
no = new int[ 3 ];
no[ 0 ] = 1;
no[ 1 ] = 2;
no[ 2 ] = 3;
}
int Fruit::print_type()
{
return no[ 0 ];
}
void Fruit::clean()
{
delete[] no;
}
int main()
{
Fruit f;
f.initialize();
int o = f.print_type();
std::cout << o;
f.clean();
return 0;
}
Please, read about constructor in C++. You don't know about the elementary things in OOP C++.
#include "Fruit.h"
void Fruit::initialize() {
int no[] = {1, 2, 3};
}
This is not correctly. You most write this.no or no.
int Fruit::print_type() {
return type[0];
}
What is variable type?
I have:
car.cc
#include "car.h"
#include <iostream>
using namespace std;
extern "C" Car* create_object()
{
return new Car;
}
Car::Car() {
this->maxGear = 2;
this->currentGear = 1;
this->speed = 0;
}
void Car::shift(int gear) {
if (gear < 1 || gear > maxGear) {
return;
}
currentGear = gear;
}
void Car::brake() {
speed -= (5 * this->getCurrentGear());
std::cout<<"THE SPEED IS:" <<speed<<std::endl;
}
extern "C" void destroy_object( Car* object )
{
delete object;
}
car.h
#ifndef VEHICLES_CAR_H
#define VEHICLES_CAR_H
// A very simple car class
class Car {
public:
Car();
void shift(int gear);
void accelerate();
void brake();
private:
int maxGear;
int currentGear;
int speed;
};
#endif /* VEHICLES_CAR_H */
test.cc
#include "/home/car.h"
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
/* on Linux, use "./myclass.so" */
void* handle = dlopen("/usr/lib/libCarTest.so", RTLD_LAZY);
int (*result)(int);
if (!handle)
{
}
/*dlsym(handle,"accelerate");
cout<<"IN HERE: "<<endl;
dlsym(handle,"brake");
dlclose(handle);*/
Car* (*create)();
void (*destroy)(Car*);
dlerror();
create = (Car* (*)())dlsym(handle, "create_object");
destroy = (void (*)(Car*))dlsym(handle, "destroy_object");
Car* carr = (Car*)create();
carr->brake();
destroy( carr );
dlclose(handle);
/*
Car carr;
carr.brake();
* compilation g++ test.cpp -o tst /path/libcar.so
*/
return 0;
}
After creating libMyLib.so and install it in /usr/lib i've tried to compile test.cc using: g++ test.cc -o tst -ldl. WHY do i need to include -lMyLib? is there a way to compile the code without libMyLib.so? Secondly why dlsym(handle,"brake") is not working? If i change dlsym (Car* (*).... with dlsym(handle,"brake") i get nothing. why?
Appreciate
WHY do i need to include -lMyLib?
Because you need to link to the Car::brake method.
Secondly why dlsym(handle,"brake") is not working?
Because there is no brake symbol. The method Car::brake has a complicated mangled (implementation-defined) name. You can see this in the output of nm -D.
AFAIK, you can solve it by
making all the methods of Car virtual (they will be called through a pointer, so no linking will be needed)
doing it the old C way, ie. export a free function brake() that would call the Car::brake method from the .so
making all the public methods of Car inline and defining them in the header.
emulating the virtual table approach (as we do it in C)
Combining the last two approaches:
class Car {
public:
void brake() { brake_impl(this); }
private:
void (*brake_impl)(Car*);
void do_brake(); // this would be the actual implementation
Car() : brake_impl([] (Car* c){ c->do_brake(); }) { ... }
};
Of course you could split the implementation and the interface so it's not such a mess.