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

Błąd w przykładzie 20.1

Ostatnio zmodyfikowano 2010-09-16 17:39
Autor Wiadomość
Dirkaeth
Temat założony przez niniejszego użytkownika
Błąd w przykładzie 20.1
» 2010-09-16 13:47:47
Nie rozumiem dokładnie dlaczego podany w kursie przykład 20.1 nie kompiluje się u mnie tak jak powinien. Moja wiedza na temat C++ nie wykracza powyżej 19 poprzednich rozdziałów tutejszego kursu.
Przykład analizowałem przez dłuższy czas i zauważyłem, że błąd występuje z kompilacją 73 linijki kodu.

bufor.replace( pozycja, pozycja1, bufor1 );
 

W samym fragmencie kodu nie wykryłem żadnego błędu. Dostrzegłem za to fakt, że po przetworzeniu 65 linijki:

sscanf( bufor1.c_str(), "%d", & zmienna );


nie można w żaden sposób wywołać, ani wykonać jakiejkolwiek operacji na zmiennej bufor. W tym także zastąpić liczbę jaka była w buforze zmienną o 1 większą od tej liczby.  Wskaźnik bufora pozostał bez zmian i chciałbym wiedzieć dlaczego występuje błąd kompilacji.

Udało mi się "naprawić" program dodając bibliotekę <cmath> i zmieniając wyżej podaną - 65 linijkę na:

C/C++
for( int i = 1; i <= pozycja1; i++ )
     zmienna +=(( int ) bufor1[ i - 1 ] - 48 ) * pow( 10, pozycja1 - i );

Nie jest to profesjonalne rozwiązanie, a ja nie jestem profesjonalistą, ale przynajmniej działa...

Niżej podaje oryginalny przykład 20.1 oraz przerobiony przeze mnie.
Przy okazji... w cytacie na 72 i 74 pozycji jest literówka :P.

C/C++
//Funkcje z parametrami referencyjnymi-------
#include <conio.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream> //nowa biblioteka
void OdczytPliku( const std::string & nazwapliku, std::string & bufor );
void Algorytm( std::string & bufor, short & zmienna, int & Wynik );
void ZapisPliku( const std::string & nazwapliku, const std::string & bufor );
std::string PL( std::string & znak );

int main()
{
    using std::string;
    using std::cout;
    const string NAZWAPLIKU = "mojplik.txt";
    string danepliku;
    short x = 0;
    int wynik = 0;
   
    OdczytPliku( NAZWAPLIKU, danepliku );
    Algorytm( danepliku, x, wynik );
    ZapisPliku( NAZWAPLIKU, danepliku );
    cout << PL( danepliku );
   
    getch();
    return 0;
}
//odczytuje dana z pliku
void OdczytPliku( const std::string & nazwapliku, std::string & bufor ) {
    using std::fstream;
    fstream plik;
    std::string bufor1;
   
    plik.open( nazwapliku.c_str(), std::ios::in );
    if( plik.is_open() ) {
        while( !plik.eof() ) {
            getline( plik, bufor1 );
            bufor1 += "\n";
            bufor += bufor1;
        }
    } else
         std::cout << "Brak mojego pliku !";
   
}
//funkcja pobiera dane z wcześniej wczytanego pliku i modyfikuje je wg prostego wzoru
void Algorytm( std::string & bufor, short & zmienna, int & Wynik ) {
    short pozycja, pozycja1;
    std::string bufor1;
    std::stringstream IntToStr;
   
    if( bufor.find( 'ż' ) ) {
        //zapisuje pozycje literki ż
        pozycja = bufor.find( 'ż' );
        // przesuwamy pozycje o 2
        pozycja += 2;
        //wycinamy z całego buforu 10 pozycji od pozycji
        bufor1.assign( bufor, pozycja, 10 );
        if( bufor1.find( ' ' ) ) {
            //zapisuje pozycje spacji
            pozycja1 = bufor1.find( ' ' );
            //następnie zostawiamy tylko liczbę
            bufor1.assign( bufor1, 0, pozycja1 );
            //zamieniamy stringa na inta
            sscanf( bufor1.c_str(), "%d", & zmienna );
            //wykonujemy działanie
            Wynik = 2 * ++zmienna + 15;
            //zamieniamy inta na stringa
            IntToStr << zmienna;
            IntToStr >> bufor1;
            IntToStr.clear(); // zerowanie IntToStr
            //zastępujemy liczbą jaka była w buforze liczbą o 1 większą
            bufor.replace( pozycja, pozycja1, bufor1 );
            //tan if ma słyżyć też zastąpienu tylko drugiego wystąpienia liczby czyli w wyrażeniu 2 * liczba + 15
            if( bufor.find( "funkcja" ) ) {
                pozycja = bufor.find( '2', bufor.find( "funkcja" ) );
                bufor.replace( pozycja + 4, pozycja1, bufor1 );
            }
            //pozostaje jeszcze zmienić wynik na wyżej obliczony
            if( bufor.find( "k to " ) ) {
                pozycja = bufor.find( ' ', bufor.find( "k to " ) );
                //ponownie IntToString
                IntToStr << Wynik;
                IntToStr >> bufor1;
                bufor.replace(( pozycja + 4 ), bufor1.length(), bufor1 );
            }
            //       std::cout << bufor;
           
        }
        if( bufor.find( "!" ) )
        if( bufor.find( "." ) ) {
        }
    } else
         std::cout << "Brak szukanej litery!";
   
}
//zapisuje dane do pliku mojplik
void ZapisPliku( const std::string & nazwapliku, const std::string & bufor ) {
    using std::fstream;
    fstream plik;
   
    plik.open( nazwapliku.c_str(), std::ios::out );
    if( plik.is_open() ) {
        plik << bufor;
    } else
         std::cout << "Brak mojego pliku !";
   
}
//poprawnie wyswietla polskie znaki w konsoli
std::string PL( 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;
}

C/C++
//Funkcje z parametrami referencyjnymi-------
#include <conio.h>
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
#include <sstream> //nowa biblioteka
void OdczytPliku( const std::string & nazwapliku, std::string & bufor );
void Algorytm( std::string & bufor, short & zmienna, int & Wynik );
void ZapisPliku( const std::string & nazwapliku, const std::string & bufor );
std::string PL( std::string & znak );

int main()
{
    using std::string;
    using std::cout;
    const string NAZWAPLIKU = "mojplik.txt";
    string danepliku;
    short x = 0;
    int wynik = 0;
   
    OdczytPliku( NAZWAPLIKU, danepliku );
    Algorytm( danepliku, x, wynik );
    ZapisPliku( NAZWAPLIKU, danepliku );
    cout << PL( danepliku );
   
    getch();
    return 0;
}
//odczytuje dana z pliku
void OdczytPliku( const std::string & nazwapliku, std::string & bufor ) {
    using std::fstream;
    fstream plik;
    std::string bufor1;
   
    plik.open( nazwapliku.c_str(), std::ios::in );
    if( plik.is_open() ) {
        while( !plik.eof() ) {
            getline( plik, bufor1 );
            bufor1 += "\n";
            bufor += bufor1;
        }
    } else
         std::cout << "Brak mojego pliku !";
   
}
//funkcja pobiera dane z wcześniej wczytanego pliku i modyfikuje je wg prostego wzoru
void Algorytm( std::string & bufor, short & zmienna, int & Wynik ) {
    short pozycja, pozycja1;
    std::string bufor1;
    std::stringstream IntToStr;
   
    if( bufor.find( 'ż' ) ) {
        //zapisuje pozycje literki ż
        pozycja = bufor.find( 'ż' );
        // przesuwamy pozycje o 2
        pozycja += 2;
        //wycinamy z całego buforu 10 pozycji od pozycji
        bufor1.assign( bufor, pozycja, 10 );
        if( bufor1.find( ' ' ) ) {
            //zapisuje pozycje spacji
            pozycja1 = bufor1.find( ' ' );
            //następnie zostawiamy tylko liczbę
            bufor1.assign( bufor1, 0, pozycja1 );
            //zamieniamy stringa na inta
            //sscanf( bufor1.c_str(), "%d", & zmienna ); //<=========== Zostawiłem w cytacie, bo tak ładnie wygląda
            for( int i = 1; i <= pozycja1; i++ )
                 zmienna +=(( int ) bufor1[ i - 1 ] - 48 ) * pow( 10, pozycja1 - i ); //<== Moja poprawka
            //wykonujemy działanie
            Wynik = 2 * ++zmienna + 15;
            //zamieniamy inta na stringa
            IntToStr << zmienna;
            IntToStr >> bufor1;
            IntToStr.clear(); // zerowanie IntToStr
            //zastępujemy liczbę jaka była w buforze liczbą o 1 większą
            bufor.replace( pozycja, pozycja1, bufor1 );
            //ten if ma słyżyć też zastąpienu tylko drugiego wystąpienia liczby czyli w wyrażeniu 2 * liczba + 15
            if( bufor.find( "funkcja" ) ) {
                pozycja = bufor.find( '2', bufor.find( "funkcja" ) );
                bufor.replace( pozycja + 4, pozycja1, bufor1 );
            }
            //pozostaje jeszcze zmienić wynik na wyżej obliczony
            if( bufor.find( "k to " ) ) {
                pozycja = bufor.find( ' ', bufor.find( "k to " ) );
                //ponownie IntToString
                IntToStr << Wynik;
                IntToStr >> bufor1;
                bufor.replace(( pozycja + 4 ), bufor1.length(), bufor1 );
            }
            //       std::cout << bufor;
           
        }
        if( bufor.find( "!" ) )
        if( bufor.find( "." ) ) {
        }
    } else
         std::cout << "Brak szukanej litery!";
   
}
//zapisuje dane do pliku mojplik
void ZapisPliku( const std::string & nazwapliku, const std::string & bufor ) {
    using std::fstream;
    fstream plik;
   
    plik.open( nazwapliku.c_str(), std::ios::out );
    if( plik.is_open() ) {
        plik << bufor;
    } else
         std::cout << "Brak mojego pliku !";
   
}
//poprawnie wyswietla polskie znaki w konsoli
std::string PL( 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;
}
P-22033
marek
problemy z programem 20.1
» 2010-09-16 17:39:42
Zauważyłem że w funkcji Algorytm  funkcja
sscanf( bufor1.c_str(), "%d", & zmienna );
powoduje zawieszenie programu.

Można to naprawić zamieniając w/w funkcję na:           
C/C++
istringstream iss( bufor1 );
iss >> zmienna; );

Oczywiście, w funkcji Algorytm należy dodać
using std::istringstream;
P-22036
« 1 »
  Strona 1 z 1