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ą... #include <iostream> #include <string> #include <fstream> #include <sstream>
struct druzyny { 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 ) for( int i = 1; i <= liczbadruzyn; i++ ) wyswietlanie( przetworzenie( tabela, i ) ); std::cin.get(); return 0; }
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; }
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; }
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 |
|
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. |
|
DejaVu |
» 2010-09-20 18:38:44 Nie możesz zwracać referencji na obiekt, który jest tymczasowy.
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ę. |
|
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. |
|
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ę. |
|
« 1 » |