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.

[C++] Dodawanie spacji po każdej danej zapisywanej do pliku.

darecky17 26 Lut 2011 20:48 2805 11
  • #1 26 Lut 2011 20:48
    darecky17
    Poziom 8  

    Witam!
    Mam do napisania program dziennik. Generalnie już wszystko mi działa, jednak potrzebne są drobne poprawki.
    Otóż mam funkcję dodawanie ocen i wszystko ok jest, oceny z każdego przedmiotu dla kazdej osoby zapisuje w innym pliku, problem jest jedynie z tym, ze oceny w plikach zapisują się jedna po drugiej... I potem gdy mam odczytywanie ocen dla kazdej osoby to wyswietlają mi się rządki wierszów ocen, ale niestety ciągiem, bez żadnych spacji tudzież innych "przerywaczy". Jak mozna zrobić żeby ta spacja sie tam pojawiała?

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0 11
  • Pomocny post
    #2 27 Lut 2011 13:48
    azra
    Poziom 16  

    Co robi ta linijka?

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Zadaj sobie również pytanie, co robi endl, którym strzelasz na lewo i prawo. ;)
    W ogóle to ten kod to jest mieszanka C i C++... W C++ masz takie ładne strumienie, którymi się tak różowiutko i przyjemnie pracuje z plikami, a wybierasz fopen i spółkę? ;)

    Później napiszę coś o samym programie, ale pewnie do zmiennej "a" (dlaczego nie stringi a tablice char?) trzeba by ową spację dodać.
    Strasznie sobie utrudniasz.

    1
  • #3 27 Lut 2011 14:16
    darecky17
    Poziom 8  

    Znalazłem odpowiedź ;)

    strcat(a, " ");

    Uczę się na lekcjach C tylko, niestety nie wiem jak to wykonać w samym C (pewnie by się nie dało), a w C++ znalazłem kilka fajnych rzeczy, które mi się przydają... Dlatego taka mieszanka.

    Dodano po 2 [minuty]:

    azra napisał:
    Co robi ta linijka?
    Kod: cpp
    Zaloguj się, aby zobaczyć kod



    Czyszczenie bufora wejściowego.

    Dodano po 2 [minuty]:

    Co do endl to chodzi o to, żeby to wszystko ładnie wyglądało ( to tylko niewielka część programu) ;)
    Powiem szczerze, że nie wybieram się na informatykę, nie twierdzę, że coś umiem nawet -> to zlepek tego, co przestudiowałem przez kilka dni. I działa. A to najwazniejze ;) Program jest na zaliczenie tylko.

    0
  • Pomocny post
    #4 27 Lut 2011 16:41
    azra
    Poziom 16  

    Nie, fflush(stdin) to niezdefiniowane zachowanie. Może zdarzyć się wszystko, łącznie z tym, że zadziała tak jak byś się tego spodziewał. ;)
    fflush() działać ma tylko dla strumieni wyjścia (i NULL), nie strumieni wejścia.
    Czyszczenie bufora stdin to np:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Akurat to radziłbym poprawić, żeby się nie przyczepiono. Bo formalnie, to jest błąd. :P

    Punkty mogą też polecieć za użycie niebezpiecznego gets() (użyj fgets() jeśli już chcesz się z C babrać): http://www.gidnetwork.com/b-56.html

    endl poza tym, że dodaje '\n' do strumienia, to jeszcze dodaje std::flush (które robi mniej więcej to samo co fflush() ), co może mieć wpływ na wydajność programu, ale w Twoim przypadku to nie ma większego znaczenia. ;)
    Nie rozumiem tylko dlaczego to:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod
    miałoby być bardziej czytelne niż:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod
    ;)

    No i co nie masz racji, spokojnie dałoby się to napisać w czystym C. Zresztą, prawie to zrobiłeś. ;)

    1
  • Pomocny post
    #5 28 Lut 2011 09:27
    Dariusz Bismor
    Poziom 17  

    Szczerze mówiąc (jako nauczyciel programowania) ja bym za taki kod nie wstawił oceny pozytywnej. Mieszanina C i C++ i niepotrzebne używanie operacji niskiego poziomu (gets()) plus wszystko to co wytknął kolega Azra, nie mówiąc już o niuansach współpracy bibliotek stdio i iostream. Znacznie lepiej jest uczyć się jednego języka i bibliotek, które dla niego stworzono.

    Dariusz

    1
  • Pomocny post
    #6 28 Lut 2011 09:56
    antekone
    Poziom 16  

    Skoro uczysz się samego C, nie używaj C++, ani obiektów typu cin, cout.

    Przy okazji, jeśli korzystasz z Visual Studio, przestań używać funkcji pokroju gets() - zamień je na bezpieczniejsze gets_s(). Ta druga funkcja jako dodatkowy argument przyjmuje wielkość bufora docelowego, dzięki czemu masz pewność, że nie nadpisze pamięci spoza bufora, który jej dałeś. Jeśli używasz gcc, skorzystaj z fgets.

    Twój przykład zawiera pewien klasyczny problem nadpisania stosu, dzięki czemu przy pomocy danych wejściowych można przechwycic kontrolę nad programem i wykorzystać program do uruchomienia własnego, często złośliwego, kodu ;). Problemem jest deklaracja bufora a, który jest wielkości 5 bajtów, oraz użycie funkcji gets(), przekazując jej ten bufor. Funkcja gets() nie potrafi sprawdzić, czy użytkownik wpisał mniej niż 5 bajtow, ponieważ nic nie wie o wielkości bufora a. Dlatego jeśli użytkownik wpisze 10 bajtów, pierwsze 5 bajtów wskoczy do bufora a, ale kolejne 5 bajtów zostanie zapisane poza buforem, w wyniku czego zmienne zaalokowane w tych miejscach w pamięci zostaną nadpisane, a program znajdzie się w stanie nieokreślonym.

    1
  • #7 28 Lut 2011 19:43
    darecky17
    Poziom 8  

    Już śpieszę z wyjaśnieniami.

    Na lekcjach mamy i C i C++ wobec tego, gdyż używamy cin i cout ;)
    Zaliczenie polega na tym, że mam zaprezentować program - już działający jako exe i zmienić jakąś rzecz (żeby nauczyciel widział że znam kod, że sam go pisałem). C mam dopiero od września przy 1h w tyg ;) Tak naprawdę na lekcjach mieliśmy - podstawy komunikacji z użytkownikiem, pętle, tablice i ostatnio były funkcje. Czyli z wiedzą z samych lekcji niewiele bym zrobił. Ocena za zaliczenie jest w sumie tylko po to, by mieć co wstawić do dziennika... Sprawami o których mówicie będę się przejmował, jeśli na studiach pojawi mi się programowanie. Teraz chodzi tylko o to, by dostać ocenę bardzo dobrą za to ,że program działa ( a obecnie działa mi poprawnie - zapisuje dane uczniów, dodaje oceny, liczy średnie z ocen, na tego postawie wystawia oceny i liczy srednie uczniów, poza tym wyświetla listę wszystkich uczniów i dane pojedynczego wybranego ucznia i wszystkie informacje przechowuje w plikach tekstowych).

    Wasze rady są bardzo cenne i jeśli będę musiał kontynuować nauke C/C++ na studiach - na pewno z nich skorzystam ;) A z tego co napisałem w tym programie pewnie dużo zapomnę, bo często opierałem się o przykłady z różnych stron i dostosowałem to wszystko do mojego programu - jakby nie patrzeć poświęciłem na to ok 20h.

    Jeszcze raz dziękuję za pomoc.

    PS: Oczywiście wszyscy otrzymują "pomógł" za zaangażowanie.

    0
  • Pomocny post
    #8 28 Lut 2011 20:00
    azra
    Poziom 16  

    Problem w tym, że właśnie na gets() może Ci się wywalić przy nauczycielu. Podajesz do gets() bufor o długości 5 znaków, a on weźmie i wpisze 180 znaków - i co? I pewnie się wywali. :P

    Twoje szczęście, że akurat kolejność operacji wygląda tak, że nawet jak gets() "trochę" nadpisze zmienne (tablica b, l, wskaźniki FILE*), to sprintf() czy fopen() to zaraz "poprawi".
    Jeśli nauczyciel rzeczywiście sprawdza tylko na podstawie działania pliku exe, to ja bym się nie cieszył na Twoim miejscu. :P Oznacza to tylko tyle, że nie nauczy Cię podstaw poprawnego kodowania. Czyli marnuje Twój czas.

    0
  • #9 28 Lut 2011 20:06
    darecky17
    Poziom 8  

    Oczywiście dodałem zabezpieczenia poprzez ify i do while w różnych kombinacjach ;)
    Nic poza 1,2,3,4,5,6 nie przejdzie ;)

    Dodano po 4 [minuty]:

    Oo mam jeszcze jeden pomysł na zmiane - czy można jakoś zrobić tak że jeśli jakiś plik nie istnieje <=> stwórz go w przeciwnym wypadku wykonaj reszte? Coś z ifem, tyle wiem. Nie wiem jak sprawdzić, czy dany plik istnieje.

    0
  • Pomocny post
    #10 28 Lut 2011 20:07
    azra
    Poziom 16  

    Jeśli użyłeś gets(buf) lub scanf("%s", buf) - to na nic zabezpieczenia. :P Możesz kodem rzucić? :>

    0
  • #11 28 Lut 2011 21:40
    darecky17
    Poziom 8  

    Poszło na PW.

    Dodano po 10 [minuty]:

    Co prawda, zauważyłem właśnie, że moje zabezpieczenia działaja tylko w przypadku liczb których nie obejmuje dziennik ( czyli oprócz 1-6 oceny i max nr z dziennika) a zapętlają się jeśli poda się literkę ;) muszę nad tym popracować.

    Dodano po 2 [minuty]:

    PS: przy podawaniu ocen jest ok, zapętla przy podawaniu nr z dziennika.

    Dodano po 1 [godziny] 16 [minuty]:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    hih zrobione i na literki zabezpieczenie ;)

    0
  • #12 28 Lut 2011 22:04
    azra
    Poziom 16  

    Mieszasz, oj mieszasz. ^^ Można też tak (bez używania funkcji z biblioteki standardowej C):

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  Szukaj w 5mln produktów