• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Tablice string o nieograniczonym rozmiarze

Object Storage Arubacloud
0 głosów
666 wizyt
pytanie zadane 29 stycznia 2018 w C i C++ przez silka nauka pasja Nowicjusz (190 p.)

Siema wszystkim może na początek wycinek treść z zadania:

"Napisz program, który pozwala użytkownikom zapisywać, kiedy ostatnio rozmawiali ze swoimi znajomymi.  Użytkownicy powinni mieć możliwość dodawania nowych znajomych (tylu, ile tylko chcą!) oraz przechowywania liczby dni, które upłynęły od czasu ostatniej rozmowy z danym znajomym."

A oto i problem: 

Dlaczego tablica stringow nie chce pomnożyć swojego wymiaru *2 gdy zostaje zapełniona?? jak zmienię wszędzie string na char to literki ładnie zapełniają tablice bez końca, a gdy string dojdzie do ustalonego z góry rozmiaru (w tym przypadku 3) to wyskakuje "STRING.EXE"przestał działać.

Czytałem, że polecacie biblioteke STL, vektory itd. ale to mam za dwa rozdziały dopiero, chce to zrobić bez ich pomocy...Dziękuję z góry za odpowiedź, pozdrawiam i wstawiam kod !!!

#include <iostream>
#include <string>

using namespace std;


string *zwiekszTablice (string* w_family, int *rozmiar)
{
    *rozmiar *= 2;
    string *w_nowe_wartosci = new string[ *rozmiar ];

for ( int i = 0; i < *rozmiar; ++i )
{
    w_nowe_wartosci[ i ] = w_family[ i ];
}

delete [] w_family;

return w_nowe_wartosci;
}
void drukujTablice (string *w_family, int rozmiar, int zajete_pola)
{
    cout << "Calkowity rozmiar tablicy: " << rozmiar << endl;
    cout << "Liczba zajetych pol tablicy: " << zajete_pola<< endl;
    cout << "Wartosci w tablicy: " << endl;

for ( int i = 0; i < zajete_pola; ++i )
    {
        cout << "w_wartosci[" << i << "] = " << w_family[ i ] << endl;
    }

}


int main()
{

int nastepny_element=0;
string ksywa;
int rozmiar=3;
string *w_family = new string[rozmiar];

cout<<"podaj ksywe:"<<endl;
getline(cin,ksywa);


while(ksywa !="a")

{


     if ( rozmiar == nastepny_element + 1 )
    {

        w_family = zwiekszTablice( w_family, & rozmiar );
    }

        w_family[ nastepny_element ] = ksywa;
        nastepny_element++;

        cout << "Oto biezce parametry tablicy: " << endl;
        drukujTablice( w_family, rozmiar, nastepny_element );
        cout << "Podaj a (a - wyjscie z programu): ";
        cin >> ksywa;

}
delete [] w_family;

cin.ignore ();
cin.get ();
return 0;
}


P.S byl podobny temat z identycznym zadaniem, ale zostawienie samego komentarza nie przesuwa posta na pierwszą stronę wiec zakaldam nowy ;) 

komentarz 29 stycznia 2018 przez CzikaCarry Szeryf (75,340 p.)
Nie znam się za bardzo, bo w c/cpp siedziałem bardzo krótko, ale możesz spróbować zrobić tablicę stringów albo skorzystać z funkcji malloc z c :)
komentarz 29 stycznia 2018 przez silka nauka pasja Nowicjusz (190 p.)
ok będę próbował dzięki za komentarz, czekam na jeszcze jakieś wskazówki ;)
komentarz 29 stycznia 2018 przez j23 Mędrzec (194,920 p.)

malloc() w C, a new w C++ - lepiej się tego trzymaj.

komentarz 29 stycznia 2018 przez CzikaCarry Szeryf (75,340 p.)
Tak jak mówiłem, nie znam się, ale można zrobić sprytny trick i wykorzystać później funkcję realloc do powiększenia bufora, ale nie wiem czy to będzie lepsze od tworzenia nowej tablicy i kopiowaniu ze starej :)
komentarz 29 stycznia 2018 przez j23 Mędrzec (194,920 p.)

Gdyby tu chodziło o tablicę int[], char[] czy inną jakiegoś POD-a, to wtedy mógłbyś użyć malloc()/realloc(), ale mowa jest o tablicy std::string[], która musi być odpowiednio stworzona, tzn. poza przydzieleniem pamięci muszą być jeszcze wywołane konstruktory, a wspomniane funkcje tego nie zrobią. Analogicznie z free() - nie wywoła destruktorów, delete to zrobi.

 

 

3 odpowiedzi

0 głosów
odpowiedź 11 lutego 2018 przez mokrowski Mędrzec (155,460 p.)
wybrane 11 lutego 2018 przez silka nauka pasja
 
Najlepsza

Eh... 

#include <iostream>

// Pamiętaj, takie komentowanie jest "patologiczne" ale chcesz 
// dokładnie wiedzieć co się dzieje... 

// XXX: Żebyś wiedział że tam coś jest... 
void fillTable(std::string * table, size_t size) {
    for(size_t i = 0; i < size; ++i) {
        table[i] = std::string("wartość ") + std::to_string(i);
    }
}

// Pokazuje zawartość tablicy
void showTable(std::string * table, size_t size) {
    std::cout << "Zawartość tablicy:\n";
    for(size_t i = 0; i < size; ++i) {
        std::cout << table[i] << '|';
    }
    std::cout << '\n';
}

// Powiększa tablicę o czynnik x 2
void growTable(std::string ** table, size_t& size) {
    // Nowa, 2 x większa tablica... 
    std::string * newTable = new std::string[size * 2];
    // Kopiowane tablicy "na piechotę"... 
    for(size_t i = 0; i < size; ++i) {
        newTable[i] = (*table)[i];
    }
    // I uaktualnienie size
    size *= 2;
    // WAŻNE!!! Usunięcie pierwotnej tablicy
    // Inaczej grozi wyciek pamięci... 
    delete [] *table;
    // Przypisanie nowej do wskaźnika
    *table = newTable;
}

int main() {
    // Tworzenie tablicy i jej wypełnienie
    size_t tableSize = 10;
    std::string * table = new std::string[tableSize];
    fillTable(table, tableSize);

    // Prezentacja pierwotnej tablicy
    std::cout << "Tablica pierwotna size = " << tableSize << '\n';
    showTable(table, tableSize);

    // Prezentacja nowej tablicy.
    // Część danych będzie 'pusta'
    growTable(&table, tableSize);
    std::cout << "Tablica powiększona size = " << tableSize << '\n';
    showTable(table, tableSize);

    // Obowiązkowe usunięcie tablicy.
    // Inaczej wyciek pamięci.
    delete [] table;
}

Wynik:

Tablica pierwotna size = 10
Zawartość tablicy:
wartość 0|wartość 1|wartość 2|wartość 3|wartość 4|wartość 5|wartość 6|wartość 7|wartość 8|wartość 9|
Tablica powiększona size = 20
Zawartość tablicy:
wartość 0|wartość 1|wartość 2|wartość 3|wartość 4|wartość 5|wartość 6|wartość 7|wartość 8|wartość 9|||||||||||

 

0 głosów
odpowiedź 29 stycznia 2018 przez mokrowski Mędrzec (155,460 p.)
1. Zakładasz nową tablicę z std::string o rozmiarze 2 x większym niż pierwotna.

2. Kopiujesz dane ze starej do nowej.

3. Usuwasz starą tablicę.

Ogólnie będziesz miał wiele new oraz delete [] i z dużym prawdopodobieństwem się pomylisz. No ale chcesz...
komentarz 29 stycznia 2018 przez silka nauka pasja Nowicjusz (190 p.)
ok super też obadam :) dam znać i oddam głos jak już skończe;)
komentarz 4 lutego 2018 przez silka nauka pasja Nowicjusz (190 p.)

@mokrowski, kurde nie wiem o co chodzi morduje się z tym już parę dni i dalej to samo. Czy to może być wina kompilatora??

komentarz 5 lutego 2018 przez mokrowski Mędrzec (155,460 p.)
No to pokaż kod... Chcę wiedzieć co już wymyśliłeś zanim zaproponuję jakieś rozwiązania.

Nie sądzę by to był błąd kompilatora :-)
komentarz 5 lutego 2018 przez silka nauka pasja Nowicjusz (190 p.)

@mokrowsk Ehh wszystko czego próbowałem pokasowałem ;P, ale mam tu dwa kody ktore zostaly:


/////////////////////////////////1 SPOSÓB///////////////////////////////

string *tablica_lista= new string[30];

void powieksz_tablice(int ilosc_elemnentow)
         {
           string *tablica_lista2 = new string[ilosc_elemnentow];

           for(int i=0; i<ilosc_elemnentow; ++i)

            {
                tablica_lista2[i]=tablica_lista[i];
            }

           delete [] tablica_lista;
           tablica_lista=tablica_lista2;
         }

/////////////////////////////////2 SPOSÓB///////////////////////////////

string *tablica;
int rozmiar=0;
cout <<"podaj rozmiar tablicy";
cin>>rozmiar;

string *bufor = new string[rozmiar];

for(int i=0; i<rozmiar; i++)

        {
            bufor[i];
            cout<<"["<<i<<"]";

        }

        for(int i=0; i<rozmiar; i++)

        {
            tablica[i] = bufor[i];

        }

delete []bufor;



for(int i=0; i<rozmiar; i++)
        {
            tablica[i]=bufor[i];
        }

//////////////////////////////////////////////////////////

tylko cały czas mi się wydaje, że przecież taką samą funkcję mam na samym początku. Mam na myśli tą:

string *zwiekszTablice (string* w_family, int *rozmiar)
{
    *rozmiar *= 2;
    string *w_nowe_wartosci = new string[ *rozmiar ];
 
for ( int i = 0; i < *rozmiar; ++i )
{
    w_nowe_wartosci[ i ] = w_family[ i ];
}
 
delete [] w_family;
 
return nowe_wartosci

albo już tak długo nad tym ślęczę, że już wyłączyło mi się myślenie ;P 

0 głosów
odpowiedź 11 lutego 2018 przez silka nauka pasja Nowicjusz (190 p.)
up :)

Podobne pytania

0 głosów
0 odpowiedzi 599 wizyt
pytanie zadane 18 listopada 2017 w C i C++ przez Dordonmegazordon Początkujący (350 p.)
0 głosów
1 odpowiedź 226 wizyt
pytanie zadane 16 października 2017 w C i C++ przez LightInWindow Użytkownik (720 p.)
0 głosów
2 odpowiedzi 1,335 wizyt
pytanie zadane 6 października 2015 w C i C++ przez Pscoolka Nowicjusz (240 p.)

92,570 zapytań

141,422 odpowiedzi

319,644 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...