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

ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb

DuMaM 19 Kwi 2014 15:03 4095 32
  • #1 13524890
    DuMaM
    Poziom 10  
    Witam

    Niedawno zacząłem swoją przygodę z AVR'ami. Po zapoznaniu już trochę z tematem chciałem wyświetlić kilka rzeczy na LCD, lecz napotkałem pewien problem. Nie wiem czemu jak wyświetlam dowolny string o długości N, który jest zapisany w tablicy o tej samej długości, to na końcu otrzymuję 1-2 różne znaki (najczęściej chińskie). Co ciekawe znaki chińskie wyświetlane są zawsze, nie zależnie od długości stringu. Tekst który ma być wyświetlony pojawia się dopiero w momencie, gdy długość tablicy jest równa N+1. Gorzej jest z wartościami całkowitymi. Jak się wpisze samą wartość np. jakiegoś int'a to otrzymuje się zawsze przekłamane wartości (przynajmniej mi się nie udało uzyskać właściwej liczby).

    Próbowałem z różnymi bibliotekami dla LCD - tu mam na myśli znanego wszystkim Pana Mirka i radzia (tu link), lecz problem jest nadal ten sam. Wyświetlacz jest oparty na sterownikach do HD44780 (dokładny model to:QC1602Av2.0).

    Pracuję w Eclipse, pod Ubuntu. Jako, że Windows 8.1 odmówił współpracy dla AVR'ów. Rodzaj komunikacji z wyświetlaczem jest dla podpiętego pinu do RW oraz w trybie pracy 4bitowej. Poniżej wrzucam zdjęcia i fragment kodu, opartego na bibliotece radzia, aby każdy miał możliwość wglądu.

    main.c
    Kod: text
    Zaloguj się, aby zobaczyć kod


    konfiguracja biblioteki wyświetlacza
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Zdjęcia obrazujące problem:
    ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb
    ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb
  • #2 13525094
    Przemo1268
    Poziom 20  
    Prawdopodobnie problem leży w tym, że biblioteka wyświetla kolejno wszystkie znaki z tablicy do momentu wystąpienia znaku 0x00. Spróbuj na końcu napisu wstawić znak "\0" (ma on długość jednego znaku, jego wartość to 0x00).
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #3 13525242
    el2010tmp
    Poziom 25  
    Albo wpisz po prostu:
    char napis_v1[]="Ala ma kota";

    Kompilator sam dopisze co trzeba.
  • #4 13525292
    2rs232
    Poziom 18  
    Tak jak koledzy wcześniej napisali problemem jest brak znaku NULL na końcu twoich stringów. Krótki opis o c-stringach znajdziesz na początku tego artykułu
    c-string
  • #5 13525312
    tadzik85
    Poziom 38  
    Przemo1268 napisał:
    Prawdopodobnie problem leży w tym, że biblioteka wyświetla kolejno wszystkie znaki z tablicy do momentu wystąpienia znaku 0x00. Spróbuj na końcu napisu wstawić znak "\0" (ma on długość jednego znaku, jego wartość to 0x00).
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Gorszego rozwiązania pewnie nie ma.

    Pomijam fakt ze kompilator na pewno wypluł warning dane nie mieszczą się w tablicy
  • #6 13525324
    DuMaM
    Poziom 10  
    Początkowo też tak myślałem.

    Pokażę wam drugi kod, w którym pojawił się problem.

    main
    Kod: text
    Zaloguj się, aby zobaczyć kod


    budowa struktury w zegar.h
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Problem jest chyba troche bardziej złożony, ponieważ teraz długość tablicy potrzebnej do przechowania stringu jest o 3-4 komórki dłuższa niż powinna. Czasem też zmieniają się ustawienia wyświetlacza np teraz mam dostęp tylko do jednego wiersza... Nie mogę wysyłać tak jak sugerowaliście przez cudzysłów, ponieważ będę nadpisywał poszczególne elementy stringu.

    Nie wiem może problem jest po stronie komunikacji, albo funkcji atoi(wiem że jest ona wykorzystywana u pana Mirka w bibliotece wyświetlacza).
    edit: właśnie sprawdziłem dla sprintf'a jest to samo, a patrząc po zachowaniu zmiennych mam wrażenie że przy każdym zapisaniu danych do tablicy jest tak jakby dopisywany kolejny "/0"
    czyli po 3 użyciu bufor mam cos takiego:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    zamiast
    Kod: text
    Zaloguj się, aby zobaczyć kod

    ale nie mam pojęcia skąd to się bierze...

    PS: Ktoś zna komendę na włączenie 2 linii wyświetlacza? :c
  • #7 13525395
    Przemo1268
    Poziom 20  
    tadzik85 napisał:
    Przemo1268 napisał:
    Prawdopodobnie problem leży w tym, że biblioteka wyświetla kolejno wszystkie znaki z tablicy do momentu wystąpienia znaku 0x00. Spróbuj na końcu napisu wstawić znak "\0" (ma on długość jednego znaku, jego wartość to 0x00).
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Gorszego rozwiązania pewnie nie ma.

    Pomijam fakt ze kompilator na pewno wypluł warning dane nie mieszczą się w tablicy


    Dlaczego uważasz że kompilator "wypluje warning"? Przecież została zadeklarowana tablica o rozmiarze 12 elementów, do której wpisujemy 12 znaków. Autor deklarował tablicę o zdefiniowanym rozmiarze do której wpisywał wartość początkową. Nie znając intencji Autora, dlaczego akurat używa tablicy o określonym rozmiarze do przechowywania tekstu nie można twierdzić czy rozwiązanie jest dobre czy nie. Skoro twierdzisz że to rozwiązanie jest gorsze to chociaż uzasadnij dlaczego.
  • #8 13525408
    tadzik85
    Poziom 38  
    To po co to zero na końcu?
  • #9 13525442
    Przemo1268
    Poziom 20  
    tadzik85 napisał:
    To po co to zero na końcu?


    Dlatego, bo niektóre kompilatory nie umieszczają na końcu tablicy znaku NULL. Kiedyś pisałem funkcję wyświetlającą tekst na procesory freescale. Funkcja wyświetlała kolejno znaki z tablicy do momentu napotkania znaku NULL. Niestety, brak umieszczenia na końcu łańcucha znaków kodu NULL powodował wyświetlanie zawartości pamięci ram za tablicą. Ten sam objaw pojawia się u Autora.
  • #10 13525456
    tadzik85
    Poziom 38  
    Przemo1268 napisał:
    tadzik85 napisał:
    To po co to zero na końcu?


    Dlatego, bo niektóre kompilatory nie umieszczają na końcu tablicy znaku NULL. Kiedyś pisałem funkcję wyświetlającą tekst na procesory freescale. Funkcja wyświetlała kolejno znaki z tablicy do momentu napotkania znaku NULL. Niestety, brak umieszczenia na końcu łańcucha znaków kodu NULL powodował wyświetlanie zawartości pamięci ram za tablicą. Ten sam objaw pojawia się u Autora.



    Wskaż więc kompilator który tak zrobił. Każdy string kończy się zerem.
    A błędem kolegi był niewłaściwy rozmiar tablicy, pewnie otrzymał odpowiedni warning na ten temat który zignorował.
    A wymuszenie zera jak ty to zrobiłeś skutkuje tym ze string zakończony jest własnym zerem i dodanym przez ciebie.
  • #11 13525577
    Przemo1268
    Poziom 20  
    tadzik85 napisał:
    Przemo1268 napisał:
    tadzik85 napisał:
    To po co to zero na końcu?


    Dlatego, bo niektóre kompilatory nie umieszczają na końcu tablicy znaku NULL. Kiedyś pisałem funkcję wyświetlającą tekst na procesory freescale. Funkcja wyświetlała kolejno znaki z tablicy do momentu napotkania znaku NULL. Niestety, brak umieszczenia na końcu łańcucha znaków kodu NULL powodował wyświetlanie zawartości pamięci ram za tablicą. Ten sam objaw pojawia się u Autora.



    Wskaż więc kompilator który tak zrobił. Każdy string kończy się zerem.
    A błędem kolegi był niewłaściwy rozmiar tablicy, pewnie otrzymał odpowiedni warning na ten temat który zignorował.
    A wymuszenie zera jak ty to zrobiłeś skutkuje tym ze string zakończony jest własnym zerem i dodanym przez ciebie.


    Proszę bardzo - na życzenie :) Procesor DSP56 - rdzeń 16-bitowy. Kompilator Metrowerks CodeWarrior 5.6. Reszta znajduje się na screenach. Tadzik85 masz rację w tym co piszesz ale jak widzisz, nie zawsze każdy kompilator działa tak samo.
    ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb
  • #12 13525587
    tadzik85
    Poziom 38  
    policz znaki "SYSTEM URUCHOMIONY"

    <rotfl>

    Tu pewnie też ignorowało się ostrzeżenia kompilatora?

    Policz zera zawarte w stringu który był wyświetlany poprawnie. Niech zgadnę 2?
  • #13 13525638
    Przemo1268
    Poziom 20  
    Ale to wynika z tego, że zadeklarowałeś tablicę o rozmiarze większym, niż wartość jaką ją inicjujesz (i wtedy wszystkie pozostałe elementy, które nie zostały zainicjowane przyjmują wartość 0). Z tym warningiem też nie zawsze jest jak piszesz - w moim kompilatorze nie było żadnego ostrzeżenia, pomimo tego, że znak NULL nie mieścił się w tablicy. My wiemy jak są przechowywane zmienne w pamięci ale początkujący nie muszą na początku zdawać sobie z tego sprawy. Jak im zaczniemy pisać o takich niuansach to tylko ich to zniechęci. Z czasem sami dojdą "jak to działa". W Visualu np. jest coś takiego, że zmienna, która nie została zainicjowana przyjmuje losową wartość podczas normalnego działania aplikacji, ale gdy wejdziesz w tryb debugowania, taka zmienna przyjmie wartość 0. Gdy zdarzy Ci się zapomnieć zainicjować zmienną to pojawia się problem - aplikacja przestaje działać gdy w opcjach kompilatora wybierasz "Release" :)
  • #14 13525652
    tadzik85
    Poziom 38  
    Przemo1268 napisał:
    Ale to wynika z tego, że zadeklarowałeś tablicę o rozmiarze większym, niż wartość jaką ją inicjujesz (i wtedy wszystkie pozostałe elementy, które nie zostały zainicjowane przyjmują wartość 0). Z tym warningiem też nie zawsze jest jak piszesz - w moim kompilatorze nie było żadnego ostrzeżenia, pomimo tego, że znak NULL nie mieścił się w tablicy. My wiemy jak są przechowywane zmienne w pamięci ale początkujący nie muszą na początku zdawać sobie z tego sprawy. Jak im zaczniemy pisać o takich niuansach to tylko ich to zniechęci. Z czasem sami dojdą "jak to działa". W Visualu np. jest coś takiego, że zmienna, która nie została zainicjowana przyjmuje losową wartość podczas normalnego działania aplikacji, ale gdy wejdziesz w tryb debugowania, taka zmienna przyjmie wartość 0. Gdy zdarzy Ci się zapomnieć zainicjować zmienną to pojawia się problem - aplikacja przestaje działać gdy w opcjach kompilatora wybierasz "Release" :)


    Więc nie karm ludzi pouczeniami, bo popełniasz dokładnie takie same błędy.
    Stringi kończą się zerem. Problemem była za mało wartość tablicy.
    Warning może się nie pojawić jak się je wyłączy.

    Po za tym tworzenie napisów ze zdeklarowana długością tylko prosi się o problemy.

    A wyżej pokazany przez ciebie przykład z wariora, pokazuje jak niewłaściwie rozwiązuje się problemy, chcąc być mądrzejszym od kompilatora. Kompilator zrobił to co mu poleciłeś, nie działa zwalasz winę na niego. A swoje rozwiązanie uważasz za słuszne.
  • #15 13525700
    Przemo1268
    Poziom 20  
    tadzik85 napisał:
    Przemo1268 napisał:
    Ale to wynika z tego, że zadeklarowałeś tablicę o rozmiarze większym, niż wartość jaką ją inicjujesz (i wtedy wszystkie pozostałe elementy, które nie zostały zainicjowane przyjmują wartość 0). Z tym warningiem też nie zawsze jest jak piszesz - w moim kompilatorze nie było żadnego ostrzeżenia, pomimo tego, że znak NULL nie mieścił się w tablicy. My wiemy jak są przechowywane zmienne w pamięci ale początkujący nie muszą na początku zdawać sobie z tego sprawy. Jak im zaczniemy pisać o takich niuansach to tylko ich to zniechęci. Z czasem sami dojdą "jak to działa". W Visualu np. jest coś takiego, że zmienna, która nie została zainicjowana przyjmuje losową wartość podczas normalnego działania aplikacji, ale gdy wejdziesz w tryb debugowania, taka zmienna przyjmie wartość 0. Gdy zdarzy Ci się zapomnieć zainicjować zmienną to pojawia się problem - aplikacja przestaje działać gdy w opcjach kompilatora wybierasz "Release" :)


    Więc nie karm ludzi pouczeniami, bo popełniasz dokładnie takie same błędy.
    Stringi kończą się zerem. Problemem była za mało wartość tablicy.
    Warning może się nie pojawić jak się je wyłączy.

    Po za tym tworzenie napisów ze zdeklarowana długością tylko prosi się o problemy.

    A wyżej pokazany przez ciebie przykład z wariora, pokazuje jak niewłaściwie rozwiązuje się problemy, chcąc być mądrzejszym od kompilatora. Kompilator zrobił to co mu poleciłeś, nie działa zwalasz winę na niego. A swoje rozwiązanie uważasz za słuszne.


    Akurat w tym przypadku kompilator pracuje na ustawieniach domyślnych. Błędy są sygnalizowane gdy przekroczę rozmiar tablicy, ale nie dzieje się ze znakiem NULL (chociaż tutaj także następuje przekroczenie rozmiaru tablicy). Wcale nie uważam swojego rozwiązania za słuszne. Uważam, że czasem lepiej jest coś robić jawnie niż liczyć na kompilator bo jak widzisz na załączonych screenach, nie zawsze kompilator wykrywa wszystkie błędy, a człowiek lubi popełniać błędy. To nie kompilator ma myśleć za programistę. Programista pisze program, a kompilator wykonuje to, co mu polecono.

    ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb ATmega328p i LCD QC1602Av2.0 - Nieprawidłowe wyświetlanie stringów i liczb

    Jak widać z powyższego, lepiej nie liczyć na kompilator, że znajdzie wszystkie nasze błędy, bo można się przeliczyć.
  • #16 13525709
    tzok
    Moderator Samochody
    Problemem jest to, że tekst deklarowany jest jako tablica znaków, a inicjowany c-stringiem...

    const char PWRON[18] = "System URUCHOMIONY";
    Definiujesz tablicę o długości 18 znaków i wpisujesz do niej ciąg 19 znaków (to jest c-string, więc jest tam już \0 na końcu ale wypada poza rozmiarem tablicy, stąd powinno być ostrzeżenie kompilatora). Gdybyś zadeklarował const char PWRON[19] = "System URUCHOMIONY"; to działałoby ok.

    W linii const char PWROFF[18] = "System ZATRZYMANY\0"; tak na prawdę wpisujesz [System ZATRZYMANY\0\0] ale ostatnie \0 wypada poza tablicą. Działa, bo to ręcznie dopisane \0 mieści się w tablicy i spełnia swoje zadanie. Drugie \0, generowane automatycznie, wypada już poza tablicą (i gdybyś to wpisał do zmiennej w programie potencjalnie nadpisałbyś zawartość jakieś innej zmiennej ale również powinieneś dostać ostrzeżenie kompilatora).
  • #17 13525711
    tadzik85
    Poziom 38  
    Co tymi screenami chcesz udowodnić?

    Że popełniłeś błąd?

    Zadeklaruj te stringi poprawnie i potem pokaż jak wyglądają.
  • #18 13525756
    Przemo1268
    Poziom 20  
    tzok napisał:
    Problemem jest to, że tekst deklarowany jest jako tablica znaków, a inicjowany c-stringiem...

    const char PWRON[18] = "System URUCHOMIONY";
    Definiujesz tablicę o długości 18 znaków i wpisujesz do niej ciąg 19 znaków (to jest c-string, więc jest tam już \0 na końcu ale wypada poza rozmiarem tablicy, stąd powinno być ostrzeżenie kompilatora). Gdybyś zadeklarował const char PWRON[19] = "System URUCHOMIONY"; to działałoby ok.

    W linii const char PWROFF[18] = "System ZATRZYMANY\0"; tak na prawdę wpisujesz [System ZATRZYMANY\0\0] ale ostatnie \0 wypada poza tablicą. Działa, bo to ręcznie dopisane \0 mieści się w tablicy i spełnia swoje zadanie. Drugie \0, generowane automatycznie, wypada już poza tablicą (i gdybyś to wpisał do zmiennej w programie potencjalnie nadpisałbyś zawartość jakieś innej zmiennej ale również powinieneś dostać ostrzeżenie kompilatora).


    Masz rację z tym, że pojawiają się dwa zera. Prawdopodobnie na innym kompilatorze mogło by dojść do nadpisania danych (w tym na szczęście tego nie było chociaż szkoda bo wcześniej bym sobie uświadomił błędy, jakie robiłem). Niestety kompilator w tym przypadku nie wyświetlał żadnych ostrzeżeń (chyba że chciałem do tablicy 18-to elementowej wstawić string o 19 znakach). To, że wstawiałem do tej tablicy faktycznie 19 znaków z ostatnim znakiem NULL nie generowało błędów.
  • #19 13525768
    tadzik85
    Poziom 38  
    Sprawdziłem i nawet GCC niei generuje ostrzeżenie na brak miejsca na kończące zero w stringu.
    Ale to nie powód to takiego obejścia problemu.
    Po to istnieje możliwości deklarowania tablicy bez podanego rozmiaru.
  • #20 13525876
    tzok
    Moderator Samochody
    Użyłem domyślnie skonfigurowanego GCC i środowisko Code::Blocks (zasadniczo nie programuję w C++) i sworzyłem taki prosty projekt:
    #include <iostream>
    
    using namespace std;
    const char PWRON[18] = "System URUCHOMIONY";
    const char PWROFF[18] = "System ZATRZYMANY";
    
    int main()
    {
        cout << PWRON << endl;
        return 0;
    }


    Przy próbie kompilacji otrzymuję komunikat:
    ||=== Build: Debug in Test_var (compiler: GNU GCC Compiler) ===|
    C:\Users\Tomek\Documents\CPP\Test_var\main.cpp|4|error: initializer-string for array of chars is too long [-fpermissive]|
    ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


    Podobnie kompilator Arduino ERW zgłasza błąd:
    sketch_apr19a:1: error: initializer-string for array of chars is too long


    To nawet nie są ostrzeżenia tylko błędy, a kompilacja kończy się niepowodzeniem, dopiero użycie flagi -fpermissive umożliwia skompilowanie takiego kodu, ale nadal z ostrzeżeniem:
    ||=== Build: Debug in Test_var (compiler: GNU GCC Compiler) ===|
    C:\Users\Tomek\Documents\CPP\Test_var\main.cpp|5|warning: initializer-string for array of chars is too long [-fpermissive]|
    ||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
    
  • #21 13525943
    tadzik85
    Poziom 38  
    tzok kolego skoro masz to juz skonfigurowane prosiłbym o sprawdzenie jak C a nie C++ się zachowa.
  • #23 13526084
    tadzik85
    Poziom 38  
    tzok napisał:
    C nie zgłasza błędów... to jeszcze ktoś używa ANSI-C?


    My :D mikrokontrolerowcy.
  • #24 13526113
    tzok
    Moderator Samochody
    Czasem coś tam piszę na AVRy ale głównie w BASCOMie ew. w C++... Wyznaję zasadę, że jeśli zachodzi potrzeba użycia języka niższego poziomu to należy użyć... mocniejszego procesora ;)
  • #25 13526156
    tadzik85
    Poziom 38  
    tzok napisał:
    Czasem coś tam piszę na AVRy ale głównie w BASCOMie ew. w C++... Wyznaję zasadę, że jeśli zachodzi potrzeba użycia języka niższego poziomu to należy użyć... mocniejszego procesora ;)



    Ciekawe odwrotne to właściwego podejście. Choć dziś.....
  • #26 13526295
    tmf
    VIP Zasłużony dla elektroda
    tadzik85 napisał:
    Sprawdziłem i nawet GCC niei generuje ostrzeżenie na brak miejsca na kończące zero w stringu.
    Ale to nie powód to takiego obejścia problemu.
    Po to istnieje możliwości deklarowania tablicy bez podanego rozmiaru.


    Nie generuje bo nie ma generować. W C jest dozwolone pominięcie znaku terminatora jeśli nie mieści się w tablicy. Ale tylko terminatora, brak miejsca na dowolny inny znak wygeneruje ostrzeżenie. Inaczej jest w C++ - pominięcie terminatora nie jest dozwolone i kod:
    char x[3]="123"; zakończy się błędem.
  • #27 13527977
    DuMaM
    Poziom 10  
    Drodzy koledzy wiem jak programować w C i C++ na PC'ty więc takie, rzeczy jak Warning to dla mnie ważna sprawa i zwracam na to uwagę - kompilator nie zgłasza problemu jak się deklaruje tablice o wielkości N dla stringu o długości N ponieważ znak \0 wpisywany jest tuż za tablicą a nie w niej samej. Łatwo to sprawdzić w wyświetlając w pętli kolejne adresy tablic.
    Teraz jednak zacząłem przygodę z mikrokontrolerami i proszę jednak o skupienie się na moim problemie, bo z czymś takim się nie spotkałem.
    Po serii testów od ostatniego postu doszedłem do tego, że dla zdefiniowanej wielkości tablicy wpisywane są od końca kolejne znaki \0 zamazujące właściwą informację. Wygląda to mniej więcej tak:

    Np.
    Mam sobie string="lol\0"
    Zawartość tablicy po kolejnych operacjach na niej (np. przepisywanie poszczególnych elementów tablicy):
    1. "lol\0"
    2. "lo\0\0"
    3. "l\0\0\0"
    mniej więcej wygląda to tak. Nie wiem dlaczego tak się dzieje i w tej kwestii potrzebna mi jest wasza pomoc.

    Ps. Dla mikrokontrolerów języki wyższego poziomu (jak np. C++) nie są polecane, bo ich rozbudowane biblioteki i funkcje zżerają masę pamięci, dlatego małe układy programuje się w językach typu ASEMBLER i C. Mikrokontrolery typu ARM mają dużo większe możliwości i tam ewentualnie dopuszczane jest programowanie w C++.
  • #29 13528150
    tmf
    VIP Zasłużony dla elektroda
    DuMaM napisał:
    Drodzy koledzy wiem jak programować w C i C++ na PC'ty więc takie, rzeczy jak Warning to dla mnie ważna sprawa i zwracam na to uwagę - kompilator nie zgłasza problemu jak się deklaruje tablice o wielkości N dla stringu o długości N ponieważ znak \0 wpisywany jest tuż za tablicą a nie w niej samej. Łatwo to sprawdzić w wyświetlając w pętli kolejne adresy tablic.


    Bez urazy ale z tego co piszesz wynika jednak, że ani C, ani C++ nie znasz. Kompilator dla łańcucha składającego się z N-znaków zapisywanego do tablicy N-elementowej dla C nie generuje ostrzeżenia bo jest to poprawna operacja w tym języku. Żaden znak NUL tuż za tablicą nie jest zapisywany. Jeśli widzisz tam zera, to wynikają one wyłącznie z domyślnej wartości pamięci RAM, która jest inicjalizowana np. przez kod startowy C lub jest to po prostu przypadek.

    DuMaM napisał:
    Ps. Dla mikrokontrolerów języki wyższego poziomu (jak np. C++) nie są polecane, bo ich rozbudowane biblioteki i funkcje zżerają masę pamięci, dlatego małe układy programuje się w językach typu ASEMBLER i C. Mikrokontrolery typu ARM mają dużo większe możliwości i tam ewentualnie dopuszczane jest programowanie w C++.


    A co ma wspólnego biblioteka z językiem? Uważasz, że np. korzystanie z C++ wymusza dołączenie jakiejś magicznej biblioteki? C++ daje równie zwarty kod jak C, a oba języki (a właściwie kompilatory tych języków) w przypadkach nietrywialnych dają kod nie gorszy niż kod asemblerowy wygenerowany przez człowieka mającego skończoną ilość czasu na jego napisanie.
    BTW, piszę w C++ na AVR, co przeczy objawieniom internetowych fachowców.

    Wracając do twojego problemu - został on już dawno rozwiązany. Musisz alokując miejsce na string uwzględniać miejsce na znak NUL i tyle. W przypadku inicjalizacji tekstem, najwygodniej jest nie podawać wymiaru łańcucha, niech sobie kompilator to wyliczy sam. W ten sposób raz na zawsze rozwiązujesz problem.
  • #30 13528470
    el2010tmp
    Poziom 25  
    Może się powtarzam, ale jednak :)

    char napis_v1[]="Ala ma kota";
REKLAMA