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

Problem z ćwiczeniem 20.6.1

Ostatnio zmodyfikowano 2010-09-21 12:41
Autor Wiadomość
Dirkaeth
Temat założony przez niniejszego użytkownika
Problem z ćwiczeniem 20.6.1
» 2010-09-20 15:03:57
Witam, mam problem z ćwiczeniem 20.6. Mógłbym oczywiście go obejść i napisać program trochę inaczej, ale ciekaw jestem bardzo dlaczego występuje taki błąd...

Program "wykrzacza" się podczas odczytu przez funkcję referencyjnej (o ile mogę tak napisać) zmiennej typu string.

Nie skończyłem jeszcze pisać kodu, dlatego proszę się nie przejmować jego ogólną prezentacją...

C/C++
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

struct druzyny { //Poz. Drużyna Mecze Zwycięstwa Remisy Porażki Małe punkty Punkty Bilans
    short poz;
    std::string nazwa;
    int mecze;
    int zwyciestwa;
    int remisy;
    int porazki;
    int mpunkty1;
    int mpunkty2;
    int punkty;
    int bilans;
};
std::string czytanie( const std::string & NAZWAPLIKU, int & liczbadruzyn );
druzyny & przetworzenie( std::string & tabela, int druzyna );
void wyswietlanie( druzyny & struktura );
std::string tekstpolski( std::string );

int main()
{
    const std::string NAZWAPLIKU = "zuzel.txt";
    std::string tabela;
    int liczbadruzyn = 0;
   
    tabela = czytanie( NAZWAPLIKU, liczbadruzyn );
    /*if (liczbadruzyn>0)
        {
            druzyny test;
            for (int i=1; i<=liczbadruzyn; i++)
            {
                test=przetworzenie (tabela, i);
                //std::cout<<&test.nazwa<<\n";
                wyswietlanie (test);
            }
        }*/
    if( liczbadruzyn > 0 )
    for( int i = 1; i <= liczbadruzyn; i++ )
         wyswietlanie( przetworzenie( tabela, i ) );
   
    std::cin.get();
   
    return 0;
}
//========================================== FUNKCJE
//------------------------------- CZYTANIE
std::string czytanie( const std::string & NAZWAPLIKU, int & liczbadruzyn )
{
    using std::fstream;
   
    std::string ctntabela, bufor;
   
    fstream plik;
    int pozycja1;
   
    plik.open( NAZWAPLIKU.c_str(), std::ios::in );
    if( plik.is_open() )
    {
        while( !plik.eof() )
        {
            getline( plik, bufor );
            ctntabela += bufor + "\n";
            liczbadruzyn++;
        }
        plik.close();
        return ctntabela;
    } else std::cout << "\aBrak pliku " << NAZWAPLIKU;
   
}
//------------------------------- PRZETWORZENIE
druzyny & przetworzenie( std::string & tabela, int druzyna )
{
    int pozycja1, pozycja2;
    std::string bufor, adruzyna;
    std::stringstream inttostr;
    druzyny danedruzyny;
   
    inttostr << druzyna;
    inttostr >> adruzyna;
    inttostr.clear();
    if( tabela.find( adruzyna + ". " ) >= 0 )
    {
        pozycja1 = tabela.find( adruzyna + ". " );
        bufor.assign( tabela, pozycja1, 10 );
        pozycja2 = bufor.find( ". " );
        bufor.assign( bufor, 0, pozycja2 );
        danedruzyny.poz = atoi( bufor.c_str() );
        bufor.assign( tabela, pozycja1 + 3, 30 );
        if( bufor.find( "|" ) )
        {
            pozycja2 = bufor.find( "|" );
            pozycja1 += 4 + pozycja2;
            bufor.assign( bufor, 0, pozycja2 );
            danedruzyny.nazwa = bufor;
            bufor.assign( tabela, pozycja1, 10 );
            if( bufor.find( "|" ) )
            {
                pozycja2 = bufor.find( "|" );
                bufor.assign( bufor, 0, pozycja2 );
                danedruzyny.mecze = atoi( bufor.c_str() );
            }
        }
    }
    return danedruzyny;
}
//------------------------------- WYŚWIETLANIE
void wyswietlanie( druzyny & struktura )
{
    using std::cout;
   
    cout << struktura.poz << ". | " << struktura.nazwa << " | " << struktura.mecze << " |\n";
}
//-------------------------------
std::string tekstpolski( std::string znak )
{
    for( unsigned i = 0; i < znak.length(); i++ ) {
        switch( znak[ i ] ) {
        case 'ą':
            znak[ i ] = static_cast < char >( 165 );
            break;
        case 'ć':
            znak[ i ] = static_cast < char >( 134 );
            break;
        case 'ę':
            znak[ i ] = static_cast < char >( 169 );
            break;
        case 'ł':
            znak[ i ] = static_cast < char >( 136 );
            break;
        case 'ń':
            znak[ i ] = static_cast < char >( 228 );
            break;
        case 'ó':
            znak[ i ] = static_cast < char >( 162 );
            break;
        case 'ś':
            znak[ i ] = static_cast < char >( 152 );
            break;
        case 'ź':
            znak[ i ] = static_cast < char >( 171 );
            break;
        case 'ż':
            znak[ i ] = static_cast < char >( 190 );
            break;
        case 'Ą':
            znak[ i ] = static_cast < char >( 164 );
            break;
        case 'Ć':
            znak[ i ] = static_cast < char >( 143 );
            break;
        case 'Ę':
            znak[ i ] = static_cast < char >( 168 );
            break;
        case 'Ł':
            znak[ i ] = static_cast < char >( 157 );
            break;
        case 'Ń':
            znak[ i ] = static_cast < char >( 227 );
            break;
        case 'Ó':
            znak[ i ] = static_cast < char >( 224 );
            break;
        case 'Ś':
            znak[ i ] = static_cast < char >( 151 );
            break;
        case 'Ź':
            znak[ i ] = static_cast < char >( 141 );
            break;
        case 'Ż':
            znak[ i ] = static_cast < char >( 189 );
            break;
        }
    }
    return znak;
}

zawartość pliku zuzel.txt:

1. Marma Hadykówka Rzeszów|10|6|1|3|502-397|15|+105
2. Lotos Gdańsk|10|5|0|5|408-491|12|-83
3. Lokomotiv Daugavpils|10|3|2|5|465-434|10|+31
4. Start Gniezno|10|4|1|5|423-476|9|-53
5. GTŻ Grudziądz|10|8|0|2|522-365|19|+157
6. PSŻ Lechma Poznań|10|6|0|4|496-402|14|+94
7. Majcher Speedway Rybnik|10|5|0|5|442-444|11|-2
8. Speedway Miszkolc|10|1|0|9|324-573|2|-249
P-22169
ThudPoland
» 2010-09-20 16:41:03
Strzelam, że jest to związane z białymi znakami... Możę później, jak będę miał czas, zajmę się tym.
P-22172
DejaVu
» 2010-09-20 18:38:44
Nie możesz zwracać referencji na obiekt, który jest tymczasowy.
C/C++
druzyny & przetworzenie(...)
{
    druzyny zmienna;
    //...
    return zmienna;
}
Obiekt jest niszczony po wyjściu ze scope'a (w tym wypadku funkcji), więc posługujesz się nieprawidłowym obiektem/strukturą. Wywal tą referencję.
P-22180
ThudPoland
» 2010-09-20 20:46:13
Problem jest też związany z białymi znakami.

Edytowałem plik z drużynami, a usunąłem tam spację z każdego punktu, program się nie wykrzaczał, ale jak zauważał Pan Administrator problem tkwi także w samej konsrtukcji programu.
P-22195
Dirkaeth
Temat założony przez niniejszego użytkownika
» 2010-09-21 12:41:58
Bardzo dziękuję za pomoc.

Nie możesz zwracać referencji na obiekt, który jest tymczasowy.
C/C++
druzyny & przetworzenie(...)
{
    druzyny zmienna;
    //...
    return zmienna;
}
Obiekt jest niszczony po wyjściu ze scope'a (w tym wypadku funkcji), więc posługujesz się nieprawidłowym obiektem/strukturą. Wywal tą referencję.

Właściwie już wcześniej zauważyłem, że wyrzucenie tego znaku usprawnia program. Byłem jednak pewien, że problem tkwi w czymś innym. W przykładzie 20.2 znajduje się podobne rozwiązanie, z tą tylko różnicą, że obiekt nie jest tymczasowy. Teraz wiem, że to istotna różnica :]

Pojawiał się jeszcze problem podczas dodania nowych pozycji do pliku z wielocyfrową liczbą porządkową. Wystarczyło uwzględnić to w jednym, czy dwóch miejscach w kodzie i już wszystko działa.

Co do białych znaków... mógłbym prosić jaśniej? Usuwając spacje nie widzę żadnych istotnych zmian.

Jest jeszcze jedna sprawa: po usunięciu znaku "&" z tej funkcji oraz sprzed argumentu w funkcji wyświetlanie w programie zostaje tylko jedna zmienna (nie licząc nazwy pliku) przekazywana w funkcji przez referencje, w dodatku jest typu string. Moje pytanie brzmi: Czy do wykonania pierwszego ćwiczenia w 20 rozdz. jedynym rozwiązaniem jest posłużenie się statycznymi strukturami, utworzonymi po przetworzeniu pliku, do którego nie będzie można dodawać nowych pozycji? Przy mojej wiedzy tylko takie rozwiązanie pozwala w tym ćwiczeniu przekazywać w funkcji strukturę przez referencję.
P-22210
« 1 »
  Strona 1 z 1