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

Dlaczego funkcja LEN(text) zwraca 0 w Bascom AVR? Jak to naprawić?

mirekk36 30 Wrz 2007 13:42 2496 6
REKLAMA
  • #1 4334638
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    Witam,

    mam takie pytanko do speców od Bascoma, otóż zdeklarowałem sobie funkcję:

    Declare Function Scanstrsp(text As String , Byval Sep As String) As String


    potem jej "ciało"

    Function Scanstrsp(text As String , Byval Sep As String) As String 
    Local I As Byte
    Local M As Byte
    
      I = 1
      While I <= Len(text)
        If Mid(text , I , 1) <> Sep Then
          I = I + 1
        Else
          Exit While
        End If
      Wend
    
      I = I - 1
      Scanstrsp = Mid(text , 1 , I)
      M = Len(text)
      I = I + 1
      M = M - I
      I = I + 1
      Text = Mid(text , I , M)
    
    End Function  


    i wszystko byłoby dobrze gdyby nie to, że okazuje się iż funkcja LEN(text) ma cały czas wartość ZERO :(

    jeśli próbuję w deklaracji dać text jako Byval text as String to wtedy ta długość jakby się pojawia ale cała funkcja bierze w łeb i procek się "przerwaca" :(

    generalnie funkcja miałaby za zadanie wydzielić(zwrócić) z zadanego stringu podanego jako paramter text jego część od początku do miejsca gdzie występuje podany jako drugi parametr funkcji separator sep

    czyli np mamy string: tx = "dane:12345"

    wywołujemy funkcję

    buf = scanstrsp(tx, ":")

    i na wyjściu zmienna buf powinna zawierać "dane" natomiast zmienna tx przekazana do funkcji powinna być skrócona i zawierać już tylko "12345"

    myślę że wszystko by mi działało ładnie tylko że czegoś chyba nie wiem i na tyle ile mogłem sprawdzić to okazuje mi się że w tej mojej funkcji LEN(text) cały czas ma wartość ZERO i stąd mi to głupio działa

    może jakaś sugestia please ;)
  • REKLAMA
  • Pomocny post
    #2 4334804
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    mirekk36 napisał:
    ...może jakaś sugestia please ;)

    Zapomniałeś o
    $hwstack = 32
    $swstack = 32
    $framesize = 16
    

    Wartości w/w parametrów mogą być inne(czytaj:większe) , jeśli "obrabiasz " długie stringi.

    Poza tym , komplikujesz niepotrzebnie proste rzeczy(czytaj:nie "wgryzłeś się" w help-a) ;)
    
    Function Scanstrsp()
    Local I As Byte
    
    I = Instr(text , Sep) 'zwróć pozycję Sep w text
    If I > 1 Then           'jeśli przed ':' jest conajmniej 1 znak
       Decr I
       Scanstrsp = Left(str1 , I)
    Else
       Scanstrsp = "" 'zwróć pusty ciąg
    End If
    
    End Function
    


    Piotrek
  • REKLAMA
  • #3 4334892
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    wielkie dzięki za sugestie,

    w związku z tym, że dopiero intensywnie uczę się Bascoma, to dlatego nie zawsze jeszcze jestem w stanie na szybko doszukać się odpowiednich poleceń w helpie jak podany przez ciebie Instr ;)

    również odnośnie tych paramterów $hwstack, $swstack, $framesize i ustalania ich wartości nie jestem jeszcze w pełni świadomy jak z nich korzystać. Z tego co piszesz należy zwiększać je wszystkie naraz jak rozumiem przy pracy na dłuższych stringach - hmmm tylko żebym jeszcze czuł już dobrze te zależności. Np przy jak długich stringach już opłaca się je zwiększać i o ile? to też byłaby cenna podpowiedź dla mnie - gdybyś mógł ;)

    natomiast odnośnie samej funkcji, którą fajnie rozpisałeś i dzięki to jednak mam pytanie - bo nie widzę w niej zdeklarowanych parametrów jakie chciałbym do niej przekazać. Czy pominąłeś je tylko żeby się nie rozpisywać tutaj?

    Dodano po 15 [minuty]:

    o teraz zaczęło działać ;) tzn funkcja poprawnie zwraca wynik ale dla mnie konieczne byłoby aby ze zmiennej text wycięty został ten początek.

    w delphi delkarowałbym taką funkcję tak:

    function ScanStrSP(var text: String; sep: String[1]): String

    słówko var przed parametrem text oznacza, że zmienna przekazywana do funkcji może ulegać zmianie przez tą funkcję. A tu w Bascomie nie działa mi to - więc nadal twierdzę, że czegoś nie wiem ;) jeśli chodzi o sposoby przekazywania parametrów :(
  • REKLAMA
  • Pomocny post
    #4 4335135
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    mirekk36 napisał:
    ...również odnośnie tych paramterów $hwstack, $swstack, $framesize i ustalania ich wartości nie jestem jeszcze w pełni świadomy jak z nich korzystać.

    https://www.elektroda.pl/rtvforum/topic320029.html
    mirekk36 napisał:

    natomiast odnośnie samej funkcji, którą fajnie rozpisałeś i dzięki to jednak mam pytanie - bo nie widzę w niej zdeklarowanych parametrów jakie chciałbym do niej przekazać. Czy pominąłeś je tylko żeby się nie rozpisywać tutaj?

    Parametry funkcji , deklarujesz przy Declare Function ...
    , a samo "ciało" funkcji , może być ... he he he... gołe(bez parametrów) .
    mirekk36 napisał:
    ... o teraz zaczęło działać ;) tzn funkcja poprawnie zwraca wynik ale dla mnie konieczne byłoby aby ze zmiennej text wycięty został ten początek...

    Ogólnie:
    Byref - przekaż zmienną bezpośrednio do funkcji (domyślnie)
    Byval - przekaż kopię zmiennej

    Z "przecinką" w text

    
    Function Scanstrsp()
    Local I As Byte , Dl As Byte
    
    I = Instr(text , Sep)                                       
    If I > 1 Then                                               
       Decr I
       Dl = Len(text) - I
       Scanstrsp = Left(str1 , I)
       Text = Right(text , Dl)                                  
    Else
       Scanstrsp = ""                                           'zwróć pusty ciąg                          
    End If
    
    End Function
    


    Piotrek
  • #5 4335369
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    wielkie dzięki Zumek ;)

    problem rozwiązany, musiałem jednak tak zrobić tą funkcję aby robiła wszystko co potrzebuję ale teraz będę też na przyszłość pamiętał o funkcji InStr która na pewno się jeszcze nie raz przyda ;)

    Function Scanstrsp(text As String , Byval Sep As String) As String
    
    Local I As Byte , Dl As Byte
    
    
      I = 1
      While I <= Len(text)
        If Mid(text , I , 1) <> Sep Then
          Incr I
        Else
          Exit While
        End If
      Wend
    
      Dl = Len(text) - I
      Decr I
      Scanstrsp = Left(text , I)
      Text = Right(text , Dl)
    
    
    End Function


    teraz linijka "Text = Right(text , Dl)" działa mi poprawnie ale to chyba dzięki z kolei tej zmianie parametrów odnośnie stosu i ramki o której wcześniej wspomniałeś

    a tak z innej beczki nie działa taki np zapis:

    if Scanstrsp(tekst, ":") = "dane" then


    tylko muszę to robić tak:

    a = Scanstrsp(tekst, ":")
    if a = "dane" then

    czyli w warunku nie można tak użyć argumentu funkcji - szkoda (albo znowu czegoś nie wiem)

    za to na szczęście działa:

    lcd Scanstrsp(tekst, ":")


    Dodano po 8 [minuty]:

    no doczytałem tego linka który mi wkleiłeś odnośnie ustawień $hwstack itp - i teraz już wiem jak się z tym poruszać ;)
  • Pomocny post
    #6 4335529
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    mirekk36 napisał:
    ...a tak z innej beczki nie działa taki np zapis:

    if Scanstrsp(tekst, ":") = "dane" then


    tylko muszę to robić tak:

    a = Scanstrsp(tekst, ":")
    if a = "dane" then

    czyli w warunku nie można tak użyć argumentu funkcji - szkoda (albo znowu czegoś nie wiem).

    Za to tak działa ;)
    
    a="dana"
    if Scanstrsp(tekst, ":") = a  then
    lub
    if a=Scanstrsp(tekst, ":") then
    ...
    


    Piotrek
  • REKLAMA

Podsumowanie tematu

LABEL_AI_GENERATED
W dyskusji poruszono problem z funkcją LEN(text) w Bascom AVR, która zwracała wartość 0 podczas operacji na stringach przekazywanych do funkcji. Przyczyną problemu były niewłaściwe parametry stosu i ramki ($hwstack, $swstack, $framesize), które należy odpowiednio zwiększyć przy pracy z dłuższymi łańcuchami znaków. Zasugerowano użycie funkcji InStr do wyszukiwania separatora w tekście zamiast ręcznego iterowania po znakach, co uprościło kod i poprawiło jego działanie. Omówiono także różnicę między przekazywaniem parametrów przez wartość (Byval) a przez referencję (Byref), wskazując, że Byval powoduje kopiowanie zmiennej, co może prowadzić do problemów z modyfikacją oryginalnego tekstu. Ostatecznie poprawiona funkcja Scanstrsp zwracała oczekiwany fragment tekstu, a zmienne tekstowe były modyfikowane prawidłowo dzięki odpowiedniemu ustawieniu parametrów stosu i ramki. Dodatkowo podano przykład poprawnego porównywania wyniku funkcji z łańcuchem znaków w instrukcji warunkowej.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA