• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Segmentation fault, deprecated conversion, funkcje i łańcuchy znakowe c++

42 Warsaw Coding Academy
+1 głos
277 wizyt
pytanie zadane 9 września 2015 w C i C++ przez exinus Nowicjusz (160 p.)
zamknięte 14 września 2015 przez exinus

Witam, próbuję rozwiązać zadanie z książki "Szkoła programowania. Język c++" Stephena Praty, wydanie 5 , rok wydania 2006.

Jego treść: Napisz funkcję mającą prototyp: 

int replace(char * str, char c1, char c2);

Niech ta funkcja zastępuje każdy znak c1 występujący w łańcuchu str znakiem c2, poczym zwraca liczbę dokonanych zastapień.

Wcześniej, gdy nie stosowałem rzutowania otrzymywałem następujący błąd:


G:\CodeBlocks programy\test2\main.cpp|10|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]|

Po użyciu debuggera otrzymałem wiadomość o Segmentation fault, czyli gdzieś naruszam pamięć. Program od razu się zawiesza. 

Teoretycznie powinienem skorzystać z kwalifikatora const, ale przecież zmieniam ten łańcuch za pomocą wskaźnika, jestem tutaj skołowany.

Czy w c++ w ogóle pisze się programy przy użyciu tablic znakowych, czy korzysta się tylko ze stringów? Proszę Was o pomoc i wytłumaczenie mojego błędu/błędów ;) Pozdrawiam!

 

#include<iostream>
using namespace std;

int replace(char * str, char c1, char c2);

int main(void)
{
    char *str = (char*)"alibababa";

    cout<<replace(str,'a','s');
    cout<<str;

    return 0;
}

int replace(char * str, char c1, char c2){

    int total = 0;

    while(*str){
        if(*str == c1)
            *str = c2;
        str++;
        total++;
    }
    return total;
}


 

komentarz zamknięcia: Zadanie rozwiązane

2 odpowiedzi

+1 głos
odpowiedź 9 września 2015 przez adrian17 Mentor (353,600 p.)
wybrane 10 września 2015 przez exinus
 
Najlepsza

Po użyciu debuggera otrzymałem wiadomość o Segmentation fault, czyli gdzieś naruszam pamięć. Program od razu się zawiesza. 

Teoretycznie powinienem skorzystać z kwalifikatora const, ale przecież zmieniam ten łańcuch za pomocą wskaźnika, jestem tutaj skołowany.

Tu jest problem. To że castujesz dosłowny string (który normalnie ma typ const char[]) na char*, nie oznacza że magicznie przestaje być const - pamięć w której jest jest zazwyczaj oznaczona jako tylko do odczytu więc modyfikowanie go powoduje segfault. Musisz zrobić osobny bufor i w nim umieścić kopię stringa.

Czy w c++ w ogóle pisze się programy przy użyciu tablic znakowych, czy korzysta się tylko ze stringów?

std::string gdy tylko to możliwe.

komentarz 10 września 2015 przez exinus Nowicjusz (160 p.)

Spróbowałem to wszystko przerobić na typ string, utworzyłem osobny bufor, ale kompilator nadal krzyczy różne niefajne rzeczy:


G:\CodeBlocks programy\test2\main.cpp||In function 'int replace(std::string*, char, char)':|
G:\CodeBlocks programy\test2\main.cpp|54|error: could not convert '* str' from 'std::string {aka std::basic_string<char>}' to 'bool'|
G:\CodeBlocks programy\test2\main.cpp|55|error: no match for 'operator==' in '* str == c1'|

 

#include<iostream>
using namespace std;

int replace(string * str, const char c1, const char c2);

int main(void)
{
    string *str ;
    string cos = "alibababa";
    str = &cos;

    cout<<replace(str,'a','s');
    cout<<str;

    return 0;
}

int replace(string * str, const char c1, const char c2){

    int total = 0;

    while(*str){
        if(*str == c1)
            *str = c2;
        str++;
        total++;
    }
    return total;
}

 

Nie mam pomysłu jak to naprawić... Możecie polecić jakiś dobry materiał z łańcuchów znakowych? 

komentarz 10 września 2015 przez adrian17 Mentor (353,600 p.)
Jeśli używasz stringa, to nie używaj wskaźników. Iteruj po indeksach i działaj na str[i].
komentarz 10 września 2015 przez exinus Nowicjusz (160 p.)
edycja 10 września 2015 przez exinus

Nie mogę przekazać funkcji wskaźnika na string? W takim razie jak zmienię wartość str w main skoro przekazuję string funkcji poprzez wartość? Oto kod (uruchamia się, ale nie liczy poprawnie i zwraca nieruszony string):

 

#include<iostream>
using namespace std;

int replace(string str, char c1, char c2);

int main(void)
{
    string str = "alibababa";
    char c1 = 'a';
    char c2 = 's';

    cout<<replace(str,c1,c2)<<endl;
    cout<<str;

    return 0;
}

int replace(string str, char c1, char c2){

    int total = 0;
    int i=0;

    while(str[i]){
        if(str[i] == c1)
            str[i] = c2;
        total++;
        i++;
    }
    return total;
}

 

komentarz 10 września 2015 przez adrian17 Mentor (353,600 p.)
Bo przekazujesz string przez wartość, czyli go kopiujesz. Przekaż go przez referencję (&).
komentarz 14 września 2015 przez exinus Nowicjusz (160 p.)

Poprawiłem kod, dziękuję za wskazówki!

#include<iostream>
using namespace std;

int replace(string &str, char c1, char c2);

int main(void)
{
    string str = "alibababa";
    char c1 = 'a';
    char c2 = 's';

    cout<<replace(str,c1,c2)<<endl;
    cout<<str;

    return 0;
}

int replace(string &str, char c1, char c2){

    int total = 0;
    int i=0;

    while(str[i]){
        if(str[i] == c1){
            str[i] = c2;
            total++;
        }
        i++;
    }
    return total;
}

 

+1 głos
odpowiedź 9 września 2015 przez Rogargol Pasjonat (16,610 p.)
Tak jak kolega wyzej napisal: przerob swoj program uzywajac typu string i powinno wszystko dzialac bez problemu :)

Podobne pytania

0 głosów
3 odpowiedzi 316 wizyt
pytanie zadane 21 listopada 2015 w C i C++ przez aspoka Mądrala (5,290 p.)
0 głosów
1 odpowiedź 177 wizyt
pytanie zadane 5 kwietnia 2020 w C i C++ przez gallaxxyy Początkujący (270 p.)
0 głosów
1 odpowiedź 217 wizyt
pytanie zadane 5 sierpnia 2016 w C i C++ przez Pac Plus Mądrala (5,560 p.)

93,395 zapytań

142,388 odpowiedzi

322,566 komentarzy

62,753 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...