logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C++] Funkcja dołączająca string z jednej tablicy do drugiej bez przepełnienia

Elektronik9 14 Lip 2009 22:21 2885 18
REKLAMA
  • #1 6779565
    Elektronik9
    Poziom 30  
    Posty: 1803
    Pomógł: 21
    Ocena: 195
    Witam.
    Napisałem program z Symfonii C++ Standard, wyd. 3 z 2008r, ćwiczenie XXIII/218, w skrócie: mamy napisać funkcję, która do końca stringu będącego w jednej tablicy dołączy string będący w innej tablicy, funkcja powinna przerwać w przypadku zapełnienia całej tablicy.

    Jak zwykle będę wdzięczny za uwagi, spostrzeżenia, komentarze i wskazówki.
    Ćwiczenie było po rozdziale o tablicach, więc nie piszcie o żadnych vectorach, klasach itp :)

    #include <iostream>
    
    using namespace std;
    
    void dolacz(char docelowa[], int rozmiar_docelowej, char zrodlowa[]);
    
    int main()
    {
    	const int rozmiar=30;    // rozmiar tablicy docelowej
    	char tablica_docelowa[rozmiar]={"Czym sie rozni kaczka"};
    	char tablica_zrodlowa[]={" od labedzia?"};
    	dolacz(tablica_docelowa, rozmiar, tablica_zrodlowa);  // here we go ;)
    	return 0;
    }
    
    //***********************************************************************
    //funkcja do dolaczania stringu z tablicy zrodlowej do tablicy docelowej:
    //***********************************************************************
    void dolacz(char docelowa[], int rozmiar_docelowej, char zrodlowa[])
    {
    	int i=0,j=0,licznik_doc=0,licznik_zro=0;
    	while(docelowa[i++]) ++licznik_doc;           //ilosc liter w tablicy docelowej, od tego indeksu zaczynamy doklejanie
    	while(zrodlowa[j++]) ++licznik_zro;           //ilosc liter w tablicy zrodlowej
    	for(int i=licznik_doc; i<licznik_doc+licznik_zro; i++)
    	{
    		if(i>=rozmiar_docelowej) break;  // zapelniona cala tablica, przerywamy dzialanie funkcji
    		docelowa[i]=zrodlowa[i-licznik_doc];  // wlasciwe doklejanie
    	}
    }
  • REKLAMA
  • Pomocny post
    #2 6780341
    lord_dagoth
    Poziom 25  
    Posty: 860
    Pomógł: 68
    Ocena: 6
    Nie do końca wiem jakich uwagi oczekujesz, ale możesz zrobić tą funkcję typu bool. False'a niech zwróci, gdy musiała przerwać dodawanie ze względu na przekroczenie rozmiaru tablicy, a true gdy dodawanie się powiodło bezproblemowo. Jeżeli kiedyś w ogóle będziesz chciał użyć tej funkcji, to będziesz mógł sobie testować, czy wszystko się udało :P
  • #3 6781171
    Elektronik9
    Poziom 30  
    Posty: 1803
    Pomógł: 21
    Ocena: 195
    Dzięki za cenną uwagę. Piszcie dalej. ;)
  • REKLAMA
  • Pomocny post
    #4 6782822
    H0miczek
    Poziom 20  
    Posty: 219
    Pomógł: 55
    Ocena: 8
    z tego co widze w funkcji dolacz nie jest Ci potrzebna zmienna "j". mozesz tam rowniez uzyc "i", tylko linijke przed uzyciem ja wyzeruj.

    mozesz rowniez pochwalic sie znajomościa makrów.
    zamiast:
    const int rozmiar=30; // rozmiar tablicy docelowej
    piszesz zaraz pod includem:
    #define rozmiar 30;
    :)
  • REKLAMA
  • #5 6782846
    Elektronik9
    Poziom 30  
    Posty: 1803
    Pomógł: 21
    Ocena: 195
    j jest potrzebne imo, do wyznaczenie rozmiaru tablicy źródłowej
       while(zrodlowa[j++]) ++licznik_zro;           //ilosc liter w tablicy zrodlowej 

    w tej linijce
  • Pomocny post
    #6 6783126
    H0miczek
    Poziom 20  
    Posty: 219
    Pomógł: 55
    Ocena: 8
    mhm, a rownie dobrze mozesz zrobic
    i=0;
    while(zrodlowa[i++]) ++licznik_zro;           //ilosc liter w tablicy zrodlowej

    prawda? dziala tak samo a masz o jedną zmienną mniej. ale to tylko taka sugestia ;]
  • #7 6783150
    Elektronik9
    Poziom 30  
    Posty: 1803
    Pomógł: 21
    Ocena: 195
    Faktycznie. Dzięki. Piszcie dalej. :)
  • #9 6783318
    Elektronik9
    Poziom 30  
    Posty: 1803
    Pomógł: 21
    Ocena: 195
    Nie, bo dlaczego miało by wywalić błąd?
    W forze mamy zupełnie inny zakres ważności nazw zmiennej, więc to zewnętrzne i i i w forze to zupełnie różne i i sobie nie przeszkadzają.

    Poza tym, to nie deklaracja, tylko definicja z inicjalizacją.
  • #10 6783435
    H0miczek
    Poziom 20  
    Posty: 219
    Pomógł: 55
    Ocena: 8
    myślałam ze to ma byc to samo :P
    dalej mi ten zapis nie pasuje ale skoro tak mówisz, to pewnie tak jest. tylko w takim razie robisz kolejną niepotrzebną zmienną :D
  • #11 6783514
    Elektronik9
    Poziom 30  
    Posty: 1803
    Pomógł: 21
    Ocena: 195
    Masz rację, można tego fora było zapisać tak:
        for(i=licznik_doc; i<licznik_doc+licznik_zro; i++)

    Redukcja jednej zmiennej i zaoszczędzenie 1 czy tam 2 bajtów na integer'a. :D
  • REKLAMA
  • Pomocny post
    #12 6784091
    Raxilion
    Poziom 11  
    Posty: 14
    Pomógł: 2
    Ocena: 3
    A może coś takiego:

    void dolacz(char docelowa[], int rozmiar_docelowej, char zrodlowa[])
    {
       int licznik_doc=0,licznik_zro=0;
       while(docelowa[licznik_doc++]); --licznik_doc;
       while(docelowa[licznik_doc++] = zrodlowa[licznik_zro++])
          if(licznik_doc>=rozmiar_docelowej) break;
    }


    trochę krótsze a przy tym w drugiej pętli odrazu wynik staje się warunkiem ;] a poza tym tutaj lecą 2 inty :D

    Elektronik9 napisał:
    Redukcja jednej zmiennej i zaoszczędzenie 1 czy tam 2 bajtów na integer'a. Very Happy


    rozmiar inta zależny jest od procesora ale zazwyczaj ma 4 bajty ;]
  • Pomocny post
    #13 6784188
    Dr.Vee
    VIP Zasłużony dla elektroda
    Posty: 1784
    Pomógł: 307
    Ocena: 76
    Programowanie to nie zawody w pisaniu najkrótszego kodu z najmniejszą ilością zmiennych. W większości wypadków kompilator wygeneruje taki sam kod. Proponuję skupić się na pisaniu programów, które są czytelne dla człowieka, a optymalizacją zająć się dopiero, gdy wydajność kodu okaże się niezadowalająca. Np:
    
    #include <cstring>
    
    bool dolacz(char docelowa[], size_t rozmiar_docelowej, char zrodlowa[])
    {
        size_t znakow_w_zrodlowej = strlen(zrodlowa);
        size_t znakow_w_docelowej = strlen(docelowa);
        size_t wymagany_rozmiar = znakow_w_zrodlowej + znakow_w_docelowej + 1; // +1 na '\0'
    
        if (wymagany_rozmiar > rozmiar_docelowej)
            return false;
    
        strcpy(docelowa + znakow_w_docelowej, zrodlowa);
    
        /*
         * // albo tak: dzięki +1 kopiujemy również końcowe '\0'
         * for (unsigned i = 0; i < znakow_w_zrodlowej + 1; ++i)
         *     docelowa[znakow_w_docelowej + i] = zrodlowa[i];
         */
    
        return true;
    }


    Co prawda powyższy kod dwa razy "przechodzi" po każdej z tablic, ale dzięki temu można uniknąć kopiowania napisów przy niewystarczającej ilości miejsca.

    Pozdrawiam,
    Dr.Vee
  • #14 6829791
    several
    Poziom 15  
    Posty: 140
    Pomógł: 14
    Ocena: 1
    Ja mam tylko jedną uwagę, jeśli kolega będzie chciał wykonać wszystkie ćwiczenia z symfoni i sprawdzić wszystkie przykłady to skończy ją czytać za pół roku :) Moja rada to po większej partii materiału zrobic coś konkretniejszego, np. po lekturze funkcji, tablic i stringów zrobić kalkulator. Następnym krokiem jest gra w kółko i krzyżyk, chyba każdy na początku robił te dwa programy xD
  • #15 6831129
    Elektronik9
    Poziom 30  
    Posty: 1803
    Pomógł: 21
    Ocena: 195
    Kalkulator pisałem kilka lat temu w Pascalu (miał z 50 funkcji), a kółko i krzyżyk - pomyślę :D
  • #16 6831172
    Maciek4141
    Poziom 22  
    Posty: 538
    Pomógł: 49
    Ocena: 5
    Kółko i krzyżyk to chyba pomysł autora tutoriala "Od zera do gier kodera". Odsyłam tam, gdybyś miał jakieś problemy.
  • #17 6832481
    several
    Poziom 15  
    Posty: 140
    Pomógł: 14
    Ocena: 1
    True, wg mnie dobry tutorial napisany całkiem przejrzyście. Ja swoje "kółko i krzyżyk" napisałem ciut inaczej niż autor ale działa tak samo:)
    Jak przebrniesz przez kółko i krzyżyk to warto pomyśleć o zaimplementowaniu gry w piłkarzyki, mam na myśli tą papierową wersję :) Do tej gierki aż prosi się dopisać komputerowego przeciwnika co daje nam możliwość nauczenia się czegoś nowego :) Dla zainteresowanych polecam algorytm MinMax.
  • #18 6855854
    jackpop
    Poziom 15  
    Posty: 189
    Ocena: 4
    several napisał:
    warto pomyśleć o zaimplementowaniu gry w piłkarzyki, mam na myśli tą papierową wersję


    W konsoli? Jak byś to widział? Nie wyobrażam sobie przejrzystego interfejsu.
  • #19 6858066
    several
    Poziom 15  
    Posty: 140
    Pomógł: 14
    Ocena: 1
    Ja też nie...dobry wstępniak do interfejsu graficznego, kiedyś trzeba to ruszyć nie? ;)

Podsumowanie tematu

✨ Dyskusja dotyczy implementacji funkcji w C++ dołączającej zawartość jednego łańcucha znaków (string) z jednej tablicy znaków do drugiej, z uwzględnieniem ograniczenia rozmiaru tablicy docelowej, aby uniknąć przepełnienia. Proponowane rozwiązania obejmują funkcję zwracającą wartość bool, sygnalizującą, czy dołączenie zakończyło się sukcesem, oraz różne podejścia do liczenia długości łańcuchów i kopiowania znaków. Wskazano na możliwość uproszczenia kodu przez eliminację zbędnych zmiennych i zastosowanie pętli kopiującej z warunkiem przerwania przy osiągnięciu limitu rozmiaru. Podkreślono znaczenie czytelności kodu nad minimalizacją liczby zmiennych, z sugestią użycia standardowych funkcji bibliotecznych, takich jak strlen i strcpy, do operacji na łańcuchach znaków. W dyskusji pojawiły się także sugestie dotyczące dalszej nauki programowania poprzez tworzenie prostych projektów, takich jak kalkulator czy gra w kółko i krzyżyk, co ma pomóc w praktycznym zastosowaniu poznanych zagadnień.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA