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] - Sprintf, zwracanie const char*

PeQ13 27 Sie 2013 11:01 1350 6
  • #1 27 Sie 2013 11:01
    PeQ13
    Poziom 8  

    Mam problem z funkcją sprintf, a konkretnie z inną funkcją która przyjmuje za jeden z argumentów const char*. Najpierw fragment kodu dla wyjaśnienia:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Tu wszystko jest fajnie, wyrzuca mi ładny napis. Problem jest w tym, że mam dalej funkcję, w stylu:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    której chciałbym użyć w ten sposób

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Ale nie działa, wrzuca mi jakiś śmieć w nazwie i tyle. Z kolei coś w stylu

    Kod: c
    Zaloguj się, aby zobaczyć kod

    działa... Gdzie popełniam błąd?

    0 6
  • Pomocny post
    #2 27 Sie 2013 12:27
    beluosus
    Poziom 25  

    15 to za mało, powinno być 16 żeby null-terminator się zmieścił.

    PS
    Przy liczniku > 9999 i tak się popsuje.

    0
  • Pomocny post
    #3 27 Sie 2013 13:32
    przemko07
    Poziom 16  

    to skoro padła odpowiedz jak poradzić sobie z problemem to powiem co poszło nie tak.
    w językach kompilowanych, na przykład C oprócz zwykłej tablicy istnieje także statyczna czysta tablica.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    gdzie liczba to naprzykład
    Kod: c
    Zaloguj się, aby zobaczyć kod

    podczas przejścia preprocesora jak kompilator widzi zapis
    char liczba[10];
    to nie wolno zakładać ze stworzy się 11 elementów(dodatkowy null na końcu)
    nie wolno też zakładać że tablica będzie w 2 miejscach(wskaźnik na stosie i reszta na stercie).
    kompilator będzie tak skracał, dopracowywał kod że będzie traktował czasami taką tablice jak kilka zmiennych, i zapis
    Kod: c
    Zaloguj się, aby zobaczyć kod

    zwróci ilość elementów, czego nie da się zrobić z tablicami dynamicznymi.
    porostu podczas działania preprocesora jak gdzieś natrafi się zapis
    tablica[3]
    to wcale od poziomu assemblera nie musi być odwołanie do tablicy, tylko do konkretnego miejsca. tak jest w przypadku całkowicie jawnych tablic, gdzie wiadomo jaka wielkość w trakcie kompilacji.
    jeśli rzutujesz sobie tablice const char[] na const* char to kompilator nie ma żadnych szans żeby poznać wielkość takiej tablicy,
    const* char to wskaźnik
    natomiast
    const char[] to tablica
    to byłoby jedno i to samo gdyby nie optymalizacja kodu kompilatora.
    w twoim przypadku wystąpiła jeszcze jedna rzecz printf będzie tak długo wypisywał ciąg bajtów aż nie trafi na pusty bajt(null),
    jeśli kompilator podczas kompilacji zauważył statyczna tablice i wiedział ile ma dokładnie miejsca za alokować to nie alokował dodatkowego bajtu na null'a, bo w dalszej pracy i tak będzie wiedział jaki jest rozmiar takiej tablicy.
    podczas gdy ty rzutowałeś na const char* program w runtime nie był już w stanie określić wielkości tablicy.

    0
  • #4 27 Sie 2013 13:36
    PeQ13
    Poziom 8  

    Ok, dziękuję za odpowiedź, rzeczywiście problem tkwił w rozmiarze tablicy, Do zamknięcia :)

    0
  • #5 27 Sie 2013 20:39
    stanleysts
    Poziom 27  

    Cytat:
    na przykład C oprócz zwykłej tablicy istnieje także statyczna czysta tablica.

    Co to ma wspólnego z kodem który wrzuciłeś?

    Cytat:
    nie wolno też zakładać że tablica będzie w 2 miejscach(wskaźnik na stosie i reszta na stercie).

    Tablica jak powyżej nie trzyma nigdy żadnego wskaźnika, tylko liczba_elementów * rozmiar_elementu.

    Cytat:
    const* char
    Chyba const char* xxx albo char * const xxx, nie wiem co chciałeś osiągnąć. Prawdopodobnie to pierwsze.

    Cytat:
    jeśli kompilator podczas kompilacji zauważył statyczna tablice i wiedział ile ma dokładnie miejsca za alokować to nie alokował dodatkowego bajtu na null'a, bo w dalszej pracy i tak będzie wiedział jaki jest rozmiar takiej tablicy.


    Powodzenia w C-stringach robić coś takiego, zawsze ma być taka tablica, żeby się null-terminator zmieścił i koniec. Inaczej wychodzą dziwy.

    0
  • #6 28 Sie 2013 15:20
    przemko07
    Poziom 16  

    1)
    jest różnica pomiedzy wielkością tablic (tablica1, tablica2) jeśli:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    jeśli już nawet pozwoli skompilować drugim sposobem to tylko dzięki nowemu standardowi.

    2)
    tablica statyczna to czasami tylko miejsce na stosie. wiec będzie mieć n elementów
    tablica dynamiczna to n elementów + wskaźnik który wskazuje na tablice

    3)
    racja, pomyliłem się.

    4)
    sprawa optymalizacji kodu jest trochę nieprzewidywalna.
    czasmi po #definie stworzy Ci się tylko blok elementów a czasami tablica statyczna. nikt nie mówi że należy korzystać tylko z bloku elementów, ale należy wiedzieć że optymalizacja kodu czasami może nam popsuć coś co wygląda dobrze ze strony kodu.

    przykładowo.

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    w momencie wyliczania
    s1 zostają podstawione same stałe,
    a w momencie Convert(array) za array zostaje podstawiona liczba która oznacza wskaźnik ale to nie oznacza że ten wskaźnik gdzieś istnieje, została podstawiona zwykła liczba bo była już znana przed runtime.

    0
  • #7 28 Sie 2013 16:07
    stanleysts
    Poziom 27  

    Piszesz bardzo nieprecyzyjnie:
    1) jesli podajesz, pod spodem, że "liczba" to #define liczba XX, to nie dziw się, że nie rozumiem co chcesz powiedzieć, bo dla mnie to zwykła tablica o stałej wartości, jakbyś napisał, że to zmienna to od razu byłaby inna gadka.
    Wystarczyło napisaćł: rozmiar tablicy może być tylko stały (więc albo przez #define XX albo const int XX), albo nowe standardy pozwalają na robienie tego jako zmienna.
    A nie tak jak piszesz wcześniej.

    2). jeśli piszesz o wskaźniku to napisz, że chodzi o dynamiczną tablicę a nie w dalszym ciągu o zwykłą.

    4). Całkowicie nie o tym mówię.

    0