Klasa string - pomoc ze zrozumieniem kodu i dopisaniem modułów.

0

Mam kolejne zadanie z klasami. Tym razem na stringach więc kolejna porcja nauki będzie. Mam dopisać 3 moduły do podanej klasy: atoi, tolower, left (usuwa od lewej n znaków)
Ale jako pierwsze zadanie to raczej trzeba zrozumieć co oznacza już kod, który mamy podany. Dodałem komentarze do kodu żeby móc się odnaleźć i rozumieć to bardziej ale i tak potrzebuję pomocy w tym.

rcstring.h:

#ifndef __RCSTRING_H__
#define __RCSTRING_H__
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;

class rcstring {
    struct rctext;
    rctext* data;

public:
    class Range {
    };
    class Cref;
    rcstring();
    rcstring(const char*);
    rcstring(const rcstring&);
    ~rcstring();
    rcstring& operator=(const char*);
    rcstring& operator=(const rcstring&);
    rcstring& operator+=(const rcstring&);
    rcstring operator+(const rcstring&) const;
    friend ostream& operator<<(ostream&, const rcstring&);
    void check(unsigned int i) const;
    char read(unsigned int i) const;
    void write(unsigned int i, char c);
    char operator[](unsigned int i) const;
    Cref operator[](unsigned int i);
};
/////////////////POCZATEK STRUCT RCTEXT //////////////////
struct rcstring::rctext {
    char* s;
    unsigned int size;
    unsigned int n;

    rctext(unsigned int nsize, const char* p) //konstruktor
    {
        n = 1;
        size = nsize;
        s = new char[size + 1];
        strncpy(s, p, size); //skopiuje "size" znaków z p do s
        s[size] = '\0';
    };
    ~rctext() //destruktor
    {
        delete[] s;
    };
    rctext* detach() //funkcja detach() zwykle pozwala wątkowi kontynuować działanie niezależnie, tutaj jeszcze nie wiem o co chodzi
    {
        if (n == 1)
            return this;
        rctext* t = new rctext(size, s);
        n--;
        return t;
    };
    void assign(unsigned int nsize, const char* p)
    {
        if (size != nsize) {
            char* ns = new char[nsize + 1];
            size = nsize;
            strncpy(ns, p, size); //skopiuje "size" znaków z p do ns
            delete[] s;
            s = ns;
        }
        else
            strncpy(s, p, size);
        s[size] = '\0';
    }

private:
    rctext(const rctext&);
    rctext& operator=(const rctext&);
};
////////////////////KONIEC STRUCT RCTEXT ///////////////////////////
////////////////////POCZĄTEK CLASS CREF ////////////////////////////
class rcstring::Cref {
    friend class rcstring;
    rcstring& s;
    int i;
    Cref(rcstring& ss, unsigned int ii)
        : s(ss)
        , i(ii){};

public:
    operator char() const
    {
        cout << "operator char() const" << endl;
        return s.read(i);
    }
    rcstring::Cref& operator=(char c)
    {
        cout << "void operator = (char c)" << endl;
        s.write(i, c);
        return *this;
    }
    rcstring::Cref& operator=(const Cref& ref)
    {
        return operator=((char)ref);
    }
};
//////////////////KONIEC CLASS CREF ///////////////////////////
inline rcstring::rcstring()
{
    data = new rctext(0, "");
}

inline rcstring::rcstring(const rcstring& x)
{
    x.data->n++;
    data = x.data;
}
inline rcstring::~rcstring()
{
    if (--data->n == 0)
        delete data;
}

rcstring& rcstring::operator=(const rcstring& x)
{
    x.data->n++;
    if (--data->n == 0)
        delete data;
    data = x.data;
    return *this;
}

rcstring::rcstring(const char* s)
{
    data = new rctext(strlen(s), s);
}

rcstring& rcstring::operator=(const char* s)
{
    if (data->n == 1)
        data->assign(strlen(s), s);
    else {
        rctext* t = new rctext(strlen(s), s);
        data->n--;
        data = t;
    };
    return *this;
}

ostream& operator<<(ostream& o, const rcstring& s) //wypisanie do konsoli
{
    return o << s.data->s;
}

rcstring& rcstring::operator+=(const rcstring& s)
{
    unsigned int newsize = data->size + s.data->size;
    rctext* newdata = new rctext(newsize, data->s); //wykorzystanie konstruktora chyba
    strcat(newdata->s, s.data->s); //dopisanie na koniec newdata->s tego co po prawej
    if (--data->n == 0) //Co oznacza --data?
        delete data;
    data = newdata;
    return *this;
}

rcstring rcstring::operator+(const rcstring& s) const
{
    return rcstring(*this) += s;
}

inline void rcstring::check(unsigned int i) const
{
    if (data->size <= i)
        throw Range();
}
inline char rcstring::read(unsigned int i) const
{
    return data->s[i];
}
inline void rcstring::write(unsigned int i, char c)
{
    data = data->detach();
    data->s[i] = c;
}

char rcstring::operator[](unsigned int i) const
{
    cout << "char rcstring::operator[](unsigned int i) const" << endl; //Nie wiem na co to wypisywanie do konsoli
    check(i); //check robi: if(data->size<=i) to throw Range() ? Range to pusta klasa więc nwm;
    return data->s[i];
}

rcstring::Cref rcstring::operator[](unsigned int i) // to co wyżej tylko, że to akurat jest używane w programie patrząc na konsole
{
    cout << "Cref rcstring::operator[](unsigned int i)" << endl;
    check(i);
    return Cref(*this, i);
}

#endif /* __RCSTRING_H__ */

Plik cpp:

#include "rcstring.h"

int main()
{
#include "rcstring.h"

int main()
{
    rcstring a, b, c;
    a = "10";
    b = "ala ma kota";
    cout << a << " " << b << endl; // 10 ala ma ma kota
    c = a + b;
    cout << c << endl; // 10ala ma kota
    c = a + rcstring(" ") + b;
    cout << c << endl; //10 ala ma kota
    rcstring d("a");
    cout << d << endl; //a
    d += "ula";
    cout << d << endl; //aula
    d += "15";
    cout << d << endl; //aula15
    cout << d[3] << endl; //a
    d[3] = 'b';
    cout << d << endl; //aulb15
    d[2] = d[1] = d[0];
    cout << d << endl; //aaab15
    return 0;
}
3

To rcstring jakaś realizacja std::string. Natomiast co do tego co musisz zrobić, to tak:

  1. zdefiniować rcstring::atoi() która działa w podany sposób
rcstring s("12345");
int number = s.atoi();//number zawiera liczbę 12345
  1. rcstring::toLower które ma robić tak:
rcstring s("ABCDefgHIJk");
rcstring lowered = s.toLower();// lowered ma zawierać abcdefghijk
  1. rcstring::left(), choć lepiej pasująca do działania nazwa to byłaby rcstring::removeFromFront(int charactersNumber); to to oczywiste co ma robić, nie będę się rozpisywał.

Ok, na co powinieneś zwrócić uwagę:

  • jak przechowywane są poszczególne znaki. Tu podpowiedź - spodziewaj się czegoś w rodzaju Poly::Mono, i debugger nastawiony na przypisania, np b = "ala ma kota"; Twoim przyjacielem ^^
  • pogóglaj za sposobem zamiany łańcucha znaków na liczbę, bo chyba z gotowca atoi() nie możesz skorzystać, ani inszego std::to_string() ?
  • jak już będziesz wiedział jak klasa rcstring przechowuje znaki to nie będziesz miał problemu aby podaną ilość wyciąć od początku stringa.
0

Działa :)

Teraz się zajmę toLower()

Udało mi się wszystko zrobić :) Dziękuję MasterBLB <3 Mega mi się przydała informacja o samym tym jak mam w mainie to zadeklarować i użyć :) Wszystko działa więc Bosko :D

0

Opłacało się pomęczyć przy wielomianach, i zaprzyjaźnić z cppreference, co? :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1