Modyfikowanie napisu (string), błąd wykonania (zad. z MAIN)

0

Witam.
Program ma za zadanie pobrać dowolny napis, następnie drugi napis będący instrukcjami jego zmodyfikowania, zmodyfikować i wypisać na ekran wynik pracy.
Pełna treść: main.edu.pl/pl/user.phtml?op=showtask&task=mod&con=PAS

Oto, co mam:

#include <iostream>
#include <string>
using namespace std;

string zamien(string s, char co, char na_co)
{
       string::size_type pozycja = 0;
       for(unsigned short i = 0; i < s.size(); i++)
       {
                    if( (pozycja = s.find(co) ) == string::npos ) break;
                    else // znalezlismy literke
                    {
                        s[pozycja] = na_co;
                    }
       }
       return s;
}

string usun(string s, unsigned short ile_cyf_lb, string::size_type poz_pocz)
{
       string pomoc = s.substr(poz_pocz, ile_cyf_lb); // substring zawierajacy tylko liczbe
       char *liczba;
       pomoc.copy(liczba, string::npos);
       unsigned short lb = atoi(liczba); // zamieniamy znaki na pelnoprawna liczbe
       s.resize( s.size() - lb ); // ucinamy
       return s;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    
    string s;
    getline(cin, s);
    string operacje;
    getline(cin, operacje, 'N');
    
    unsigned short i = 0;
    while(i < operacje.size())
    {
            switch(operacje[i])
            {
                               case 'Z': // zamiana
                               {
                                     s = zamien(s, operacje[i + 2], operacje[i + 4]); 
                                     i += 6; break;
                               }
                               case 'D': // doklejenie
                               {
                                     s += operacje[i + 2];
                                     i += 4; break;
                               }
                               case 'U': // usuwanie
                               {
                                    unsigned short cyfry = 1; // w domysle od 1 do 9 tj. 1 cyfrowe
                                    for(unsigned short j = i + 1; j < operacje.size() - 1; j++)
                                    { // szukamy pozycji, w ktorej zaczyna sie kolejna operacja <=> wiemy, gdzie konczy sie 
                                      // podawanie samej liczby
                                                 if( operacje[j] == 'Z' || operacje[j] == 'D' || operacje[j] == 'U')
                                                 {
                                                     cyfry = j - (i + 1) - 2;
                                                     break;
                                                 }
                                    }
                                    s = usun(s, cyfry, i+2); 
                                    i = i + 3 + cyfry; break;
                               }
                               default: i++;
            }
    }
    
    cout << s;
} 

W bardzo wielu przypadkach program niepoprawnie się wykonuje, wypisując błąd:

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Proszę o pomoc i z góry dziękuję.

0

Jej, nawet nie wiedziałem co to debugger, ale poczytałem, sprawdziłem i błąd 'sam' się znalazł i był idiotyczny :) Otóż w funkcji usun(), string pomoc powinien być zapełniany substringiem z operacje, a nie z s. Dalej jeszcze jakiś błąd segmentacji się pojawił przy

pomoc.copy(liczba, string::npos);

i szczerze mówiąc, nie wiem dlaczego, jednak po usunięciu tej linijki oraz zamienieniu

unsigned short lb = atoi(liczba); 

na

unsigned short lb = atoi(pomoc.c_str()); 

już jest OK.
Teraz program już błędów nie pokazuje, ale problemy się mnożą... - sprawdzarka MAIN'owa daje 83 punkty i komunikat "Zła odpowiedź". Jednak sprawdzając ręcznie różne warianty wprowadzonych danych wychodzi mi dobry wynik... czy jest jakiś sposób na dowiedzenie się, dla jakich danych z testów MAIN'owych program daje błędną odp. ?

@cysiej
Być może przekombinowane, ale nie mam pomysłu na zapisanie ich inaczej...

0

Nie kompilowałem, pisane z reki ale chyba wystarczajace jest cos takiego:

 
void D(string &s,char znak)
{
	s+=znak;
}
void U(string &s,int ile)
{
	s=s.substr(0,s.size()-ile);
}
void Z(string &s,char z,char na)
{
	for(int i=0;i<s.size();i++)
		if(s[i]==z)
			s[i]=na;
}
0

Prócz tego, że moje funkcje nie przyjmują stringu przez referencję, to:

  • funkcję doklejania w zasadzie mam taką samą
  • funkcję usuwania niby inną, ale nie mam jawnie podane ile tych liter należy usunąć, więc konwersja na typ całkowity raczej jest konieczna (a to, czy samo usunięcie zrobię za pomocą substr czy erase jest chyba tym samym (aha, zapomniałem napisać - z resize coś się niedobrego działo, więc zmieniłem na erase ))
  • zamiana faktycznie sprytniejsza (i chyba szybsza? ) jest bez find, dzięki

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