Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Problem z funkcjonowaniem napisanego programu w C

damek012 24 Sty 2015 02:16 1647 35
  • #1 24 Sty 2015 02:16
    damek012
    Poziom 1  

    Chciałbym Wam przedstawić mój problem, otóż polega on na tym, że gdy kompiluję program to nic się nie dzieje. Jestem nowy w programowaniu, miałem to w liceum, przez miesiąc i teraz wymagają ode mnie nie wiadomo czego na studiach - 1 rok.

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Tak samo dzieje się przy wyszukiwaniu osoby przez numer telefonu:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Czy byłoby ktoś w stanie pomóc mi z tym kodem? Nie mam pojęcia czemu po odpaleniu programu i wpisaniu do zmiennej "szukaj" danego ciągu znaków, przed konsolą pojawia się okno z brakiem odpowiedzi.

    Dodano po 32 [minuty]:

    W nieco przerobionym programie, po odpaleniu odpluskiwacza, program zatrzymuje się w tym samym miejscu. A oto błąd który wyskakuje wraz z "... przestał działać".

    Problem z funkcjonowaniem napisanego programu w C

    0 29
  • #2 24 Sty 2015 05:37
    qbus1981
    Poziom 11  

    Dawno już w C++ nie programowałem ale nie wydaje mi się aby porównywanie łańcuchów się zmieniło :)

    Sprawdzenie

    Code:
    if (łańcuch1 == łańcuch2)

    nie zadziała w ten sposób możesz sprawdzać tylko pojedyncze znaki łańcucha:
    Code:
    if (łańcuch1[x] == łańcuch2[y])


    do porównywania łańcuchów mamy odpowiednie funkcje np:
    Code:
    strcmp(char[] a,char[] b);

    0
  • #3 24 Sty 2015 09:24
    p.kaczmarek2
    Poziom 23  

    damek012 napisał:


    Kod: cpp
    Zaloguj się, aby zobaczyć kod



    Drogi dameku, to są banalne rzeczy, jak na studiach tego nie umiesz to chyba ciężko, ale spójrz:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Tak powinno być, analogicznie dla reszty napisów, jak coś to pisz smialo to pomozemy

    0
  • #4 24 Sty 2015 12:48
    -psiak-
    Poziom 32  

    Przez ten fragment:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    W przypadku kiedy na liście brak rekordów segmentation fault jest gwarantowany.

    0
  • #6 25 Sty 2015 13:11
    mcvsama
    Poziom 15  

    Hej. Na tych studiach to jest C czy C++? Jeśli C++, to powinieneś używać std::string i porównywać a == b. Jeśli C, to const char* i strcmp(a, b) == 0. Zbaczam z tematu, ale ten kod:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    jest pisany w takim trochę stylu „C w C++” i ma błąd przepełnienia bufora. Co się stanie jeśli ktoś poda więcej niż 9 znaków? W zasadzie nawet wystarczy, że poda 8, to i tak na końcu zostanie doklejony znak \0. Więc tablica 9-elementowa nie wystarczy do wczytania typowego 9-cyfrowego numeru telefonu, bo na końcu będzie jeszcze znak \0 - potrzebujesz tablicy 10-elementowej.

    W C++ zamiast tablicy 9-znakowej lepiej użyć std::string i funkcji std::getline(std::cin, szukaj). A jeśli koniecznie musi być tablica w stylu C (bo taki jest wymóg w zadaniu), to użyj metody std::cin.getline(tablica, 9), której możesz podać limit znaków do wczytania.

    0
  • #7 25 Sty 2015 13:25
    -psiak-
    Poziom 32  

    mcvsama napisał:
    W C++ zamiast tablicy 9-znakowej lepiej użyć std::string i funkcji std::getline(std::cin, szukaj).

    Może tego nie wiesz ale to wcale nie jest to samo, poza tym C++ nie wymaga użycia std::string.

    mcvsama napisał:
    ... to użyj metody std::cin.getline(tablica, 9), której możesz podać limit znaków do wczytania.

    z operatorem strumieniowym też można użyć tego ograniczenia:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  • #8 25 Sty 2015 13:31
    mcvsama
    Poziom 15  

    -psiak- napisał:
    Może tego nie wiesz ale to wcale nie jest to samo, poza tym C++ nie wymaga użycia std::string.


    ORLY? ;-) To jest kwestia stylu programowania. C-w-C++ to udręka, nie tylko dla innych programistów, ale także dla tych, którzy sami tak piszą i później tracą czas na debugowanie.

    0
  • #9 25 Sty 2015 13:50
    -psiak-
    Poziom 32  

    Jeżeli dla ciebie tablica znakowa to już nie C++ - to diagnoza jest ewidentna - bardziej artysta niż programista.

    0
  • #10 25 Sty 2015 13:56
    mcvsama
    Poziom 15  

    -psiak-: Po prostu zapomniałeś kontekstu.

    0
  • #11 25 Sty 2015 14:12
    -psiak-
    Poziom 32  

    Kontekstu nie zapomniałem.
    Tylko że wg mnie z twojej wypowiedzi:

    mcvsama napisał:
    ... ale ten kod:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod
    jest pisany w takim trochę stylu „C w C++” ...
    jednoznacznie wynika że wg ciebie w C++ nie należy używać tablic char.
    A to z kolei mocno odbiega od prawdy.

    0
  • #12 25 Sty 2015 14:21
    mcvsama
    Poziom 15  

    Nie wynika to co napisałeś. Natomiast wynika to, że uważam, że ręczne zapewnianie (którego w kodzie brak), że dane z zewnątrz nie zepsują stanu programu to właśnie taki trochę styl „C w C++”. W przypadku tablic tak jest, w przypadku std::string już nie.

    Ty natomiast uogólniłeś sobie, że rzekomo nigdy nie należy używać tablic char w C++.

    0
  • #13 25 Sty 2015 14:32
    -psiak-
    Poziom 32  

    Najpierw pokazałem że da się kontrolować przepełnienie w przypadku tablic, a ty wciąż o swoim:

    mcvsama napisał:
    ORLY? ;-) To jest kwestia stylu programowania. C-w-C++ to udręka...
    ba, po wszystkich wyjaśnieniach:
    mcvsama napisał:
    ... W przypadku tablic tak jest, w przypadku std::string już nie.


    Może próbujesz donieść tezę - dosyć często w C++ zamiast prostej tablicy char lepiej użyć std::string lub std::vector lub std::array - z taką tezą się zgadzam. Ale samo użycie zwykłych tablic od tak nazywać "C w C++" - jakoś zakrawa na "nazi-programming".

    0
  • #14 25 Sty 2015 14:38
    mcvsama
    Poziom 15  

    -psiak- napisał:
    Najpierw pokazałem że da się kontrolować przepełnienie w przypadku tablic, a ty wciąż o swoim


    Trolololo. :-) Właśnie o to chodzi - pokazałeś, że ręcznie da się to zrobić. Dlatego „ja wciąż o swoim”, czyli o tym, że nie trzeba tego ręcznie robić.

    -psiak- napisał:
    ba, po wszystkich wyjaśnieniach:
    mcvsama napisał:
    ... W przypadku tablic tak jest, w przypadku std::string już nie.


    Czy to jest trudne do zrozumienia?

    -psiak- napisał:
    Ale samo użycie zwykłych tablic od tak nazywać "C w C++".


    A to już Twój pomysł. O co mi chodziło już wyjaśniłem. :-)

    0
  • #15 25 Sty 2015 14:45
    -psiak-
    Poziom 32  

    mcvsama napisał:
    Właśnie o to chodzi - pokazałeś, że ręcznie da się to zrobić.
    Przecież dla typu std::string w przypadku wprowadzenia telefonu to i tak należy użyć tego setw(9) bo inaczej możesz dostać 100 znakowy telefon.
    Czyli bez "robótki ręcznej" i tak się nie obejdzie.

    0
  • #16 25 Sty 2015 14:51
    mcvsama
    Poziom 15  

    Owszem, zgadza się. Jednak ja wybrał bym 100-znakowy telefon niż exploitowalny bug ala Heart Bleed. ;-) Ale tak naprawdę telefon powinien być osobnym typem, który sam potrafi się „wczytać”, zweryfikować, ograniczyć. To wszystko po to, żeby użytkownik API nie musiał w ogóle pamiętać o takich rzeczach, a także żeby ograniczyć powtarzanie tego samego kodu, jeśli pobieranie danych jest w kilku miejscach. Wtedy jak najbardziej obejdzie się bez robótki ręcznej.

    0
  • #17 25 Sty 2015 15:01
    -psiak-
    Poziom 32  

    W przypadku specjalnego typu na telefon - jak najbardziej się zgadzam, tylko jak widzę zapomniałeś o kontekście, spójrz na kod pytającego i powiedz kiedy wg ciebie będzie on w stanie napisać taki typ? No chyba że pisząc "obejdzie się bez robótki ręcznej" masz na myśli że ten typ napisze się automatycznie.
    Co do:

    mcvsama napisał:
    ... ja wybrał bym 100-znakowy telefon niż exploitowalny bug ...
    to wciąż "nie widzisz" (i właśnie nie łapę czemu) tego rozwiązania bardzo prostego, ograniczającego do 9-ciu znaków i zupełnie bez bug'ów. Czemu jako alternatywy tego prostego rozwiązania widzisz tylko nieograniczony std::string lub bug?
    (nie wspominam o specjalnym typie bo to nie na aktualne umiejętności pytającego)

    0
  • #18 25 Sty 2015 15:17
    mcvsama
    Poziom 15  

    Przecież nie proponowałem na początku pisania własnego typu, tylko std::string.

    -psiak- napisał:
    to wciąż "nie widzisz" (i właśnie nie łapę czemu) tego rozwiązania bardzo prostego, ograniczającego do 9-ciu znaków i zupełnie bez bug'ów


    Nie mówię, że std::setw nie jest alternatywą. Sam przecież też podałem przykłady z getline, w których też ręcznie wpisałem magiczną liczbę 9. Jednak w duchu C++ jest używanie samo-dbających o siebie klas, dlatego sądzę, że lepiej od razu przekonywać do takiego podejścia i zaproponować ten std::string.

    0
  • #19 25 Sty 2015 15:30
    -psiak-
    Poziom 32  

    mcvsama napisał:
    ... Sam przecież też podałem przykłady z getline, w których też ręcznie wpisałem magiczną liczbę 9...
    O tym już mówiłem, to nie to samo, jedno wczytuje do "białego znaku" drugie końca wiersza - różnica istotna.

    mcvsama napisał:
    ... Jednak w duchu C++ jest używanie samo-dbających o siebie klas ...
    Wydaje mi się że już rozumiem w czym problem - mylisz dwa pojęcia OOP i C++. Z połową twoich wypowiedzi się zgadzam więc nawet nie komentowałem, ale gdyby w twoich wypowiedziach (z którymi się nie zgadzam) zamienić "C++" na "OOP" to się zgadzam prawie w 100% (absolutna zgodność to tylko w Korei Północnej).

    0
  • #20 25 Sty 2015 15:43
    mcvsama
    Poziom 15  

    -psiak- napisał:
    mcvsama napisał:
    ... Jednak w duchu C++ jest używanie samo-dbających o siebie klas ...
    Wydaje mi się że już rozumiem w czym problem - mylisz dwa pojęcia OOP i C++.

    A czemu tak sądzisz?

    0
  • #21 25 Sty 2015 16:10
    -psiak-
    Poziom 32  

    Przecież już podałem przykład:
    ... Jednak w duchu OOP jest używanie samo-dbających o siebie klas ... - zdecydowanie, jak najbardziej, nie ma żadnych zastrzeżeń!
    ... Jednak w duchu C++ jest używanie samo-dbających o siebie klas ... - dziwne, C++ to tylko język, owszem ułatwiający pisanie w duchu OOP.
    Gdyby tak było jak mówisz to temu o to tworowi:
    http://www.cplusplus.com/reference/istream/istream/read/ nie ma miejsca w C++ (bo char * nie jest samo-dbającą o sobie klasą).

    0
  • #22 25 Sty 2015 16:20
    mcvsama
    Poziom 15  

    To w takim razie dodam, że w duchu C++ jest używanie samo-dbających o siebie klas tam, gdzie to jest możliwe. ;-) Innym założeniem C++ jest to, że jest jako-tako kompatybilny z C. Więc skoro char* jest odziedziczony po C, to wypadało by, żeby biblioteka standardowa nie utrudniała integracji kodu z C. :-)

    0
  • #23 25 Sty 2015 16:22
    ania13L
    Poziom 12  

    Na pewno temat Waszej dyskusji zainteresuje pytajacego :) I jest tak kluczowy dla rozwiazania jego problemu. Wrecz go odstaszacie od programowania moim zdaniem.

    0
  • #24 25 Sty 2015 17:02
    -psiak-
    Poziom 32  

    mcvsama napisał:
    To w takim razie dodam, że w duchu C++ jest używanie samo-dbających o siebie klas tam, gdzie to jest możliwe. ;-)
    Nadal nieprawda, skoro nawet autorzy biblioteki standardowej nie zgadzają się z tobą (czemu - czytaj niżej). Często w sieci można spotkać wyrażenia typu: - "... pod kompilatorem Dev-Cpp ..." - a przecież Dev-Cpp to nie kompilator, niektórzy bezmyślnie powtarzają, niektórzy walczą z tym wyrażeniem za każdym razem podkreślając że to bzdura. Ale to nie jest bzdura tylko skrót myślowy, ma się na myśli "... pod kompilatorem używanym przez Dev-Cpp ...". Tak samo można krytykować: - "... zdaniem mcvsama ..." - przecież mcvsama nie jest zdaniem! Wydaje mi się że gdzieś złapałeś ten skrót myślowy na temat C++ a samo-dbające się klasy. Dla mnie twoje zdanie o C++ brzmi podobnie do nawoływań nazistów albo przekazań od klechy - tylko że temat inny.

    mcvsama napisał:
    Innym założeniem C++ jest to, że jest jako-tako kompatybilny z C. Więc skoro char* jest odziedziczony po C, to wypadało by, żeby biblioteka standardowa nie utrudniała integracji kodu z C. :-)
    Tu zdecydowanie przesadzasz, przecież FILE *fd=fopen(...) nigdzie nie zniknęło, więc spokojnie można użyć przynajmniej dla ostream::write użyć referencji do std::string zamiast przekazywać dwa parametry jeden z których nie samo-dbający (oczywiście o ile autorzy biblioteki standardowej byliby zgodni z twoją tezą).

    ania13L napisał:
    Na pewno temat Waszej dyskusji zainteresuje pytajacego :) I jest tak kluczowy dla rozwiazania jego problemu. Wrecz go odstaszacie od programowania moim zdaniem.
    Jeżeli zamierza zajmować się programowaniem, to powinno go to zainteresować. Co do odstraszania - to już jest odstraszony na maksa skoro pyta o takich prostych rzeczach na forum zamiast kombinować samodzielnie.

    0
  • #25 25 Sty 2015 17:23
    mcvsama
    Poziom 15  

    Akurat ludzie zasiadający w komitecie standaryzacyjnym w kółko powtarzają jak ważne jest RAII i unikanie zarządzania zasobami w stylu C, które jest błędogenne. Bjarne wręcz mówi, że „jeśli używasz new i delete, to najprawdopodobniej robisz to źle” (w domyśle powinieneś używać smart-pointerów).

    fopen() nie zniknęło, ale to nie jest typowe C++, to jest właśnie ta kompatybilność z C. Samego fopen() się odradza używać… bo przecież trzeba potem zrobić fclose(). A skoro trzeba zamknąć plik jawnie (ręcznie), to trzeba wziąć pod uwagę wczesne returny z funkcji lub możliwość rzucenia wyjątkiem, opakować wszystko w try { } i w każdym catch upewniać się, że każdy plik został zamknięty, żeby nie było wycieków deskryptorów. Przez to kod się strasznie komplikuje. A C++-owe fstream to wszystko rozwiązuje.

    A co do .write() - czemu write()? Przecież jest w std::ostream właściwy sposób na wrzucienie std::string:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Edit: oczywiście miało być „fopen() nie zniknęło”, ale jakoś mi „nie” zniknęło. ;-)

    0
  • #26 25 Sty 2015 17:56
    -psiak-
    Poziom 32  

    Dobra rozumiem że ta dyskusja jest bezsensowna jeżeli nie jesteś w stanie odróżnić RAII (popularny wzorzec w C++) od samego C++.
    Czy rozumiesz różnicę pomiędzy zwykłym życiem od życia świętoszy?
    Co do Bjarne to dopiero C++11 pozwala w pełni obejść się bez new i delete, zaś mówiąc C++, prawdopodobnie masz na myśli od C++03
    Jak najbardziej popieram wszystkie słuszne zasady OOP (w tym RAII) ale powtarzam nie mieszaj to z C++, który jest jedynie środkiem.

    -1
  • #27 25 Sty 2015 18:11
    mcvsama
    Poziom 15  

    RAII to podstawa C++, istnieje praktycznie od jego początku, a twórcy C++ ciągle narzekają, jak to RAII w C++ jest niedoceniane i niezrozumiane.

    Ale faktycznie z takimi grami w słowa do niczego nie dojdziemy. Ale może chociaż autor wątku bardzie zainteresuje się tematem. ;-) Byłby z tego jakiś pożytek.

    -1
  • #29 25 Sty 2015 18:23
    mcvsama
    Poziom 15  

    No raczej, skoro RAII to styl programowania, a C++ to język. Dokładnie tak jak pisałem: ludzie piszący w C++ często piszą stylem C, a nie typowym dla C++ stylem używając RAII. Bo w C++ można pisać nawet w bardzo dziwne sposoby. You can write FORTRAN in any language.

    -1
  • #30 25 Sty 2015 19:14
    -psiak-
    Poziom 32  

    1. Jeszcze raz powtarzam RAII nie jest typowym stylem C++, RAII nie jest typowym stylem OOP.
    2. RAII może być zastosowano nie tylko w C++.
    3. C++ istniało na długo przed powstaniem RAII jako wzorca.

    -1