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

C++ Metoda .substr() Komunikat: std::out_of_range

Ostatnio zmodyfikowano 2017-12-22 23:01
Autor Wiadomość
kotek88
Temat założony przez niniejszego użytkownika
C++ Metoda .substr() Komunikat: std::out_of_range
» 2017-12-22 11:26:07
Witam,

mam pytanie odnośnie użycia metody ".substr" dla zmiennej typu String.

Podczas kompilacji na linux do pliku o nazwie "bin" otrzymuję komunikat:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr
/sciezka/go: linia 4:  5519 Przerwane               (zrzut pamięci) ./bin

Co robię nie tak? Czy wartości parametrów dla metody .substr są błędne? Jak poprawnie użyć tej metody w tym przypadku?

Program otwiera plik html i ma wczytac do zmiennej "records[]" oraz polaczyc w ramach jednego elementu tablicy zawartosc wierszy pliku, ktore stanowia jeden akapit kodu html.

Przyklad pliku  html:


<html>
<body>
<p>Zdanie 1.</p>
<p>Zdanie 2.</p>
<p>Zdanie 3.
   Zdanie 4.
   Zdanie 5.</p>
<p>Zdanie 6.</p>
<p>Zdanie 7.</p>
<p>Zdanie 8.</p>
</body>
</html>

Plik ma 12 wierszy i 6 rekordów. Tablica records[] ma miec 6 elementow. Element nr 3, czyli records[2] ma zawierac polaczone teksty "Zdanie 3 Zdanie 4 Zdanie 5". Jak to zrobic?

kod programu:

C/C++
#include <iostream>
#include <string>
#include <cstdio>
#include <fstream>
#include <cstdlib>
using namespace std;

//----------------------------------------------------------------

bool file_buffer( string sNazwaPliku )
{
    int n, i = 0, ile_wierszy = 0, DataCount = 0;
    string * buffer;
    string * records;
    ifstream plik;
    string wiersz;
    size_t ZnaPocz, ZnaKon;
    int Dlugosc;
    string SzukPocz = "<p>";
    string SzukKon = "</p>";
   
    //-----------------------------------
    plik.open( sNazwaPliku.c_str() );
    if( !plik.good() )
         return false;
   
    while( getline( plik, wiersz ) )
         ile_wierszy++;
   
    plik.close();
   
    //-----------------------------------
   
    plik.open( sNazwaPliku.c_str() );
    if( !plik.good() )
         return false;
   
    buffer = new string[ ile_wierszy + 1 ];
    if( buffer == NULL ) exit( 1 );
   
   
    for( n = 0; n < ile_wierszy; n++ )
    {
        getline( plik, wiersz );
        buffer[ n ] = wiersz;
        ZnaPocz = buffer[ n ].find( SzukPocz );
        ZnaKon = buffer[ n ].find( SzukKon );
        // cout << ZnaPocz << " , " << ZnaKon << endl;
       
        if( ZnaPocz != string::npos || ZnaKon != string::npos )
             DataCount++;
       
        if( ZnaPocz != string::npos && ZnaKon == string::npos )
             DataCount--;
       
    }
    buffer[ ile_wierszy ] = '\0';
   
    plik.close();
   
    //------------------------------------
    records = new string[ DataCount + 1 ];
   
    for( n = 0; n < ile_wierszy; n++ ) // Gdzie jest BŁĄD w metodzie .substr ?
    {
        ZnaPocz = buffer[ n ].find( SzukPocz );
        ZnaKon = buffer[ n ].find( SzukKon );
       
        if( ZnaPocz != string::npos || ZnaKon != string::npos )
        {
            Dlugosc = ZnaKon - ZnaPocz + 1;
            records[ i ] = buffer[ n ].substr( ZnaPocz, Dlugosc );
            i++;
        }
        if( ZnaPocz != string::npos && ZnaKon == string::npos )
        {
            i--;
            records[ i ] += buffer[ n ];
        }
    }
    records[ DataCount ] = '\0';
    //------------------------------------
   
    for( n = 0; n < ile_wierszy; n++ )
         cout << buffer[ n ] << endl;
   
    for( n = 0; n < DataCount; n++ )
         cout << records[ n ] << endl;
   
    cout << "\n\nIlosc wierszy w pliku: " << ile_wierszy << endl;
    cout << "Ilosc akapitow HTML: " << DataCount << endl;
   
    delete[] buffer;
    delete[] records;
    return true;
}
//-----------------------------------------------------------------

void cls() // Wyczysc ekran (polecenie systemowe)
{
    getchar();
    #ifdef linux
    system( "clear" );
    #endif
    #ifdef _WIN32
    system( "cls" );
    #endif
}

//-----------------------------------------------------------------

int main()
{
   
    //-----------------------------------------------------------------
   
    printf( "Buforowanie i wyswietlanie pliku." );
    printf( "\n\nDo bufora wczytano 'plik.txt'. Wyswietlam zawartosc bufora:\n\n" );
   
   
    if( !file_buffer( "plik.txt" ) )
         cout << "Nie udalo sie otworzyc pliku o podanej nazwie." << endl;
   
    printf( "\n\n...Koniec..." );
    cls();
   
    //-----------------------------------------------------------------
   
    return 0;
}


P-168056
pekfos
» 2017-12-22 18:44:45
C/C++
if( ZnaPocz != string::npos || ZnaKon != string::npos )
{
    Dlugosc = ZnaKon - ZnaPocz + 1;
    records[ i ] = buffer[ n ].substr( ZnaPocz, Dlugosc );
    i++;
}
Ten warunek dopuszcza ZnaPocz równe npos, co nie może zostać podane jako pierwszy argument substr.
P-168064
kotek88
Temat założony przez niniejszego użytkownika
» 2017-12-22 22:57:08
Czy oby na pewno? Ten warunek brzmi przecież : jeśli ZnaPocz jest różne != od npos.

Muszę prześledzić wartości jakie się pojawiają w tej pętli. Z pewnością warunek jest do poprawy, muszę jednak nad tym pomyśleć,czy tu nie potrzeba zagnieżdżonego warunku? Dziękuję za odp.
P-168070
kotek88
Temat założony przez niniejszego użytkownika
» 2017-12-22 23:01:59
Ok, chyba już rozumiem. Rzeczywiście tam jest operator LUB, więc dopuszcza npos. Warunek do poprawy. Dzięki :)
P-168071
« 1 »
  Strona 1 z 1