błąd przy dopisywaniu znaków do stringu c++

0

Witam,

Uczę się programowania c++ w ramach pewnego kursu. Oto zadanie z którym mam problem i bardzo proszę o pomoc dla nowicjusza ;):
Program na wejściu otrzymuje skrócony wyraz, a na wyjściu ma wypisywać wersje rozwiniętą. Rozwinięcie polega na tym, że przechodząc znak po znaku to gdy natrafiamy na cyfrę lub liczbę to zastępujemy to miejsce wskazaną ilością znaku, który poprzedza daną cyfrę czy liczbę. Czyli tam gdzie napotka na przykładowo zapis: A4BD, to wypisze AAAABD albo np A14BD to wypisze AAAAAAAAAAAAAABD.

Problem pojawia się w momencie dopisywania znaków do wyjsiowego stringa.
Poniżej wklejam swój kod z komentarzami:

https://ideone.com/TSvv6M

#include <iostream>
#include <string>
#include <sstream>
#include <string>

using namespace std;

int StringNaInt(string liczba) //funkcja konwertująca stringa na int
{
    int liczbaWIncie;
    istringstream iss(liczba);
    iss >> liczbaWIncie;
    return liczbaWIncie;
}

 bool czyZnakJestCyfra(char znak) //funckja sprawdzająca czy dany znak jest cyfrą lub nie
{
    if ( (znak >= '0') && (znak <= '9') )
        return true;
    else
        return false;
}

int main()
{
    string Wyraz; //wyraz wejściowy przed rozpakowaniem
    cin>>Wyraz;

    string powtarzajacySieZnak;//znak który stoi przed cyfrą lub liczbą
    int pozycja=0;
    string liczbaWyraz; //zmienna do ktorej beda dodawane cyfry

    string rozpakowywanyWyraz; //Zupełnie nowy, przekonwertowany, rozpakowany wyraz na wyjsciu z programu

    int dlugosc = Wyraz.length();//poczatkowa dlugosc wyrazu

   while (pozycja<=Wyraz.length())
    {
        //sprawdzenie czy dany znak jest cyfrą
        if( czyZnakJestCyfra(Wyraz[(char)pozycja] ) == true)
        {
            //przypisuje znak który należy powtórzyć o ilość
            //na którą wskazuje cyfra tuż przed poniższym znakiem
            powtarzajacySieZnak = Wyraz[pozycja-1];
             liczbaWyraz = Wyraz[pozycja];
             cout<<liczbaWyraz<<endl;
            //warunek sprawdzający czy kolejny znak też jest cyfra
            while( czyZnakJestCyfra(Wyraz[(char)pozycja+1] ) == true)
            {
                //zapisuje bieżącą pozycję do zmiennej LiczbaWyraz
               liczbaWyraz += Wyraz[pozycja+1];
                cout<<liczbaWyraz<<endl;
                pozycja++;
            }

            //uruchomienie funckji konwertującej stringa na int
            //odejmuję 1 ponieważ jak wiadomo pierwszy znak już jest wypisany w stringu
            (StringNaInt(liczbaWyraz)-1);
            cout<<(StringNaInt(liczbaWyraz)-1);

            for(int j = 0; j<(StringNaInt(liczbaWyraz)-1);j++)
            {
                //tutaj gubi sie program
                rozpakowywanyWyraz = rozpakowywanyWyraz+powtarzajacySieZnak;
            }
        }
        else
        {
            // biezący znak NIE jest cyfrą to po prostu przenosze biezący znak do oczekiwanego wyrazu na wyjsciu
            rozpakowywanyWyraz[pozycja]=Wyraz[pozycja];
            pozycja++;
        }

    }
    cout<<rozpakowywanyWyraz<<endl;//wyraz na wyjsciu
}
1
bool czyZnakJestCyfra(char znak) /
{
	return (znak >= '0') && (znak <= '9'); // równoważna implementacja
}

// while (pozycja<=Wyraz.length()) // wychodzisz poza tablicę!
while (pozycja<Wyraz.length())  // powinno być tak
...
	// if( czyZnakJestCyfra(Wyraz[(char)pozycja] ) // niepotrzebne rzutowanie
	if( czyZnakJestCyfra(Wyraz[pozycja])
0
ekhart napisał(a):
bool czyZnakJestCyfra(char znak) /
{
	return (znak >= '0') && (znak <= '9'); // równoważna implementacja
}

// while (pozycja<=Wyraz.length()) // wychodzisz poza tablicę!
while (pozycja<Wyraz.length())  // powinno być tak
...
	// if( czyZnakJestCyfra(Wyraz[(char)pozycja] ) // niepotrzebne rzutowanie
	if( czyZnakJestCyfra(Wyraz[pozycja])

Dzięki, ale mimo to nadal nie zostają dopisywane znaki do string'a wyjściowego

3

Ogółem, wymyślasz koło na nowo. [isdigit][1] i [std::stoi][2] wystarczy użyć.

Zobacz ile się napisałeś, a zobacz ile ja, aby osiągnąć efekt ;​)

char c;
while(cin >> c) {
    int count;
    if(cin >> count) {
        cout << string(count, c);
    } else {
        cin.clear();
        cout << c;
    }
}

https://wandbox.org/permlink/N1Iul4pP4Zz76be1
[1]: http://en.cppreference.com/w/cpp/string/byte/isdigit
[2]: http://en.cppreference.com/w/cpp/string/basic_string/stol

2

Strasznie przekombinowujesz, a wystarczy parę linijek.
https://wandbox.org/permlink/1IHCsW0OGZgMJlVz

#include <iostream>
#include <sstream>

using namespace std;

ostream& Decode(ostream& out, const string &s) {
    istringstream data(s);
    char ch;
    while (data >> ch) {
        int r;
        if (data >> r) {
            out << string(r, ch);
        } else {
            out << ch;
            data.clear();
        }
    }
    return out;
}

int main() {
    string s;
    
    while (getline(cin, s)) {
        Decode(cout, s) << endl;
    }
    
    return 0;
}
3

Odpaliłem program @Damian Jasiński w debuggerze. rozpakowywanyWyraz[pozycja]=Wyraz[pozycja]; (gdy znak nie jest cyfrą) przypisuje znak do pustego stringa. To jest UB.

1 użytkowników online, w tym zalogowanych: 0, gości: 1