Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Przerobienie pętli dla wczytywania wielu plików C++

Ostatnio zmodyfikowano 2017-02-17 07:54
Autor Wiadomość
xien
Temat założony przez niniejszego użytkownika
Przerobienie pętli dla wczytywania wielu plików C++
» 2017-02-16 11:24:45
Witam, mam taką funkcję jak poniżej i do tej pory program działał tak że miałem wprowadzane pliki i za każdym razem jak był dodawany następny plik to tamten wcześniej był zamykany a potem otwierany na nowo i dopisywany więc było to nie poprawnie. Chodzi mi o to że wprowadzam jakiś plik i z tego pliku wejscie >> dane są zapisywane do tablicy, pętla się kończy i powiedzmy że mam tą tablice na indeksach 0-5(oczywiście danych może być dowolna ilość), a gdy dodaje następny plik i wywołuję znowu tą funkcję to on mi nadpisuje te dane które dodałem wcześniej bo pętla zaczyna się od zera i nie wiem jak zrobić tak żeby funkcja zaczynała dopisywanie do tablicy do tej danej na której skończyła czyli jak wywołuje dla kolejnego pliku to żeby dopisywało do tablicy dla indeksu 678itd a nie leciało od 0. Mam jeszcze drugi problem jest pod poniższą funkcją, tam jest funkcja do powiększania tablicy i nie wiem jak się z niej pozbyć wycieków pamięci.
Z góry dziękuję za pomoc.

C/C++
void Wypisz_osoby( Studenci ** osoby, int ile_osob, string plik_wej_z_param ) {
   
    ifstream wejscie( plik_wej_z_param );
    Studenci przedmiot;
    getline( wejscie, przedmiot.nazwa_przedmiotu );
    cout << przedmiot.nazwa_przedmiotu << endl;
    getline( wejscie, przedmiot.prowadzacy );
    cout << przedmiot.prowadzacy << endl;
   
    for( int i = 0; i < ile_osob; i++ )
    {
        osoby[ i ]->nazwa_przedmiotu = przedmiot.nazwa_przedmiotu;
        osoby[ i ]->prowadzacy = przedmiot.prowadzacy;
        wejscie >> osoby[ i ]->imie >> osoby[ i ]->nazwisko >> osoby[ i ]->nr_albumu >> osoby[ i ]->ocena >> osoby[ i ]->data;
       
        cout << osoby[ i ]->imie << " " << osoby[ i ]->nazwisko << " " << osoby[ i ]->nr_albumu << " " << osoby[ i ]->ocena << " " << osoby[ i ]->data << "\n";
    }
   
    wejscie.close();
}

A tu nie wiem gdzie wsadzić delete żeby program się nie sypał
C/C++
bool Odczyt_imion( Studenci **& tablica_osoby, string plik_wej_z_param, int & rozmiar_tablicy, int & licznik ) {
    ifstream wejscie( plik_wej_z_param );
    string nazwa_przedmiotu_a;
    string prowadzacy_a;
    string imie_a;
    string nazwisko_a;
    string nr_albumu_a;
    string ocena_a;
    string data_a;
    string test;
    if( !wejscie ) {
        cout << "Nie udana proba odczytu pliku: " << plik_wej_z_param << endl;
        return EXIT_FAILURE;
    }
    else {
        getline( wejscie, nazwa_przedmiotu_a );
        getline( wejscie, prowadzacy_a );
       
        while( wejscie >> imie_a >> nazwisko_a >> nr_albumu_a >> ocena_a >> data_a ) {
            if( licznik >= rozmiar_tablicy )
            {
                rozmiar_tablicy += 1 / 2 * rozmiar_tablicy; // powiększenie rozmiaru;
                Studenci ** tmp = new Studenci *[ rozmiar_tablicy ];
                for( int i = 0; i < licznik; ++i ) tmp[ i ] = tablica_osoby[ i ];
               
                delete[] tablica_osoby;
                tablica_osoby = tmp;
                //delete[] tmp;
            }
           
            tablica_osoby[ licznik ] = new Studenci { nazwa_przedmiotu_a, prowadzacy_a, imie_a, nazwisko_a, nr_albumu_a, ocena_a, data_a };
            licznik++;
        }
       
    }
    return EXIT_SUCCESS;
}
P-157820
Nazgul
» 2017-02-17 06:30:55
Co do pierwszej funkcji.. możesz:
- użyć zmiennej statycznej w funkcji(poczytaj o zmiennych statycznych)
- stworzyć odpowiednią strukturę/klasę zawierającą plik i dane, tak żeby ze sobą grały(poczytaj o strukturach lub klasach)
- zapisywać dane w kontenerze (poczytaj o kontenerach STL)
- przesyłać do funkcji referencję na zmienną, która zapamięta na czym skończyłeś

Do wyboru do koloru;D
Te kontenery z STL chyba najbardziej ci się w tym wypadku przydadzą, ułatwią ci również dbanie o te wycieki pamięci;D

co do drugiej funkcji..
Ogólnie to nie mam pewności, ale to "rozmiar_tablicy += 1/2*rozmiar_tablicy;" to o ile się nie mylę, ale suma ciągu
x, (1/2) x, (1/2)^2 * x, (1/2)^3 * x, ..., (1/2)^n * x = 1.33333 x         dla n->oo (infinity)
także nie wiem czy na pewno się opłaca ciągle dodawać tej pamięci, skoro to tylko 1,333;D

a co do samego deletowania w tej funkcji.. masz straszny bałagan. nie wiem do końca co chcesz osiągnąć w tej funkcji..
-masz(chyba) zarezerwowaną pamięć wskaźników  tablica_osoby
-rezerwujesz pamięc wskaźników  tmp
-pod wskazniki w tmp przepisujesz wskazniki z tablica_osoby
-usuwasz pamięc wskazników z tablica_osoby
-przepisujesz adres na wskazniki z tmp do tablica_osob
-rezerwujesz pamięć zmiennych w wskaznikach w tablica_osob <--- tu jest punkt kulminacyjny

nie rozumiem co ta funkcja ma robić... ale o ile podczas wywolywania tej funkcji NIE masz zarezerwowanej pamięci dla zmiennych w wskaźnikach w tablica_osob.. oraz NIE zapominasz o usunięciu tej pamięci zmiennych, oraz pamięci wskażników w odpowiednim miejscu po wyjściu z funkcji, to MOŻLIWE że nie ma wycieku, ale naprawdę nie wiem co ten program ma robić... zainteresuj się kontenerami STL, spodobają ci się, programowanie stanie się bajką;D
(w skrócie.. ten kontener STL, to taka tablica, którą możesz sobie bez problemu powiększyć w razie potrzeb, masz różne te kontenery, vector, list, deque, queue.. z tego co widzę twój poziom to powinieneś bez problemu ogarnąć różnice między nimi;D w każdym razie zamieszczę ci krótki kod z przykładem jak to działa)
C/C++
#include <vector>

int main() {
    std::vector < int > nasza_tablica; /* w tych strzałkach zawieramy informacje jakiego typu jest nasz kontener, może być np. <Student>, o ile taką klasę stworzysz*/
   
    tablica.push_back( 4 ); // teraz pod tablica[0] mamy 4
   
    tablica.push_back( 5 ); // teraz pod tablica[0] mamy 4, a pod tablica[1] mamy 5
   
    tablica.push_back( int( 2 ) ); // tablica[0] to 4, tablica[1] to 5, tablica[2] to 2 (specjalnie napisałem tak dziwnie tego inta
    /*np. zeby dodac Student do takiego czegoś, to tak jak w tablicy dynamicznej, musisz konstruktor wywolac np. tablica.push_back(Student(.....));*/
    // aaa i jakby co to tak samo jak w tablicy.. nie mozesz np. do tej tablicy typu int wpisac elementu typu double
    int zmienna = tablica[ 2 ];
    int rozmiar = tablica.size();
    return 0;
}
P-157883
mateczek
» 2017-02-17 07:54:13
nie ma potrzeby kasowania
delete[] temp;
skasowałeś starą tablicę i przypisałeś wskaźnikowi rozmiar do nowej. nie możesz skasować tempa bo skasujesz nową !!!
P-157884
« 1 »
  Strona 1 z 1