Möglicher Fehler in Bascom 2082 mit der Funktion INSTR

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Möglicher Fehler in Bascom 2082 mit der Funktion INSTR

      Folgendes ist mir heute aufgefallen.
      Gegeben sei folgende Zeichenkette die sich in der Variablen cREC befindet:

      Source Code

      1. OK
      2. +CMGR: "REC READ","6700",,"2019/07/12,07:54:16+02"
      3. Service Team

      Die Funktion ist folgendermaßen aufgebaut:

      BASCOM Source Code

      1. Function CheckSMSpos(ByVal pStartPos As Byte) As Byte
      2. Local fS As String * 1
      3. fS = Chr(34)
      4. Incr pStartPos
      5. print #2 , "P0:" ; str(pStartPos);
      6. If pStartPos <> 0 Then
      7. SMS_Pos1 = Instr(pStartPos , cREC , "{034}")
      8. print #2 , " / P1:" ; str(SMS_Pos1);
      9. If SMS_Pos1 <> 0 Then
      10. Incr SMS_Pos1
      11. SMS_Pos2 = Instr(SMS_Pos1 , cREC , "{034}")
      12. print #2 , " / P2:" ; str(SMS_Pos2);
      13. If SMS_Pos2 = 0 Then
      14. SMS_Pos1 = 0
      15. End If
      16. End If
      17. Else
      18. SMS_Pos2 = 0
      19. End If
      20. print #2 , ""
      21. print #2 , cREC
      22. If SMS_Pos1 = 0 Or SMS_Pos2 = 0 Then
      23. CheckSMSpos = 0
      24. Else
      25. CheckSMSpos = 1
      26. End If
      27. End Function
      Display All


      Die Abfrage lautet folgendermaßen:
      SMS_Pos1 = Instr(pStartPos , cREC , "{034}")
      Die Version 2081 liefert richtig
      P0:1 / P1:17 / P2:26
      Die neue Version 2082 liefert aber falsch
      P0:1 / P1:0
      findet also den Charakter 34 (das Anführungszeichen) nicht im String.

      Als Workaround habe ich aktuell
      fS = Chr(34)
      SMS_Pos1 = Instr(pStartPos , cREC , fS)
      dann liefert auch die Version 2082 die korrekte Position.

      Eine Anmerkung noch, nicht verwirren lassen, die oben angegeben zurückgelieferten Positionen stimmen, da im zu durchsuchenden String auch noch Steuerzeichen (CRLF) enthalten sind die ja auch mitgezählt werden!
    • Mitch64 wrote:

      Im Grunde genommen stellt der Ausdruck "{034}" eine Stringkonstante mit 5 Zeichen dar.
      Ja, aber meiner Meinung nach, sollte der Compiler daraus dann eben das eine Zeichen machen (und hat es ja auch bisher so gemacht).
      Diese Schreibweise soll doch IMHO nur ein Komfort beim Programmieren darstellen und sonst nichts weiter.
      Erst mit der neuen Version von BasCom stellt sich dieses IMHO falsche Verhalten dar.
      Und diese Schreibweise wurde zumindest bisher auch beim Print-Befehl genau so verwendet und funktioniert auch aktuell.
    • Ich verstehe deine Argumentation.

      Aber angenommen jemand wollte tatsächlich nach diesem Sting "{034}" suchen wollen, wie soll man das dem Compiler mitteilen? Stichwort Escape-Zeichen.

      In C ist z.B "\n" ein NewLine.
      Sollte aber wirklich ein Backslash und ein n ausgegeben werden, müsste "\\n" geschrieben werden.

      Sowas in der Art bräuchte dann Bascom.

      Ich sehe jetzt da eingentlich keinen Fehler. Aber kannst ja mal Mark fragen, wie er argumentiert.
      Wäre mal interessant.
    • Ich habe jetzt mal ein kleines Testprogramm für 2.0.8.2 geschrieben.

      BASCOM Source Code

      1. $Regfile = "m8def.dat"
      2. $Crystal = 8000000
      3. Dim QuellString as String * 20
      4. Dim SuchString as String * 20
      5. Dim ErgebnisString as String * 20
      6. Dim Pos as Byte
      7. QuellString = "abc " + chr(34) + "def" + chr(34) + " ghi {034} jkl"
      8. SuchString = "{034}"
      9. Pos = Instr(Quellstring , Suchstring)
      10. Print QuellString
      11. Print SuchString
      12. Print Pos
      13. End ' da keine Hauptschleife
      Display All

      Dann kommt das korrekte Ergebnis:

      Heraus kommt das:
      Inhalt QuellString: abc "def" ghi " jkl
      Inhalt SuchString: "
      Pos: 5

      Wenn ich die Zeile 11 so abändere:

      BASCOM Source Code

      1. Pos = Instr(Quellstring , "{034}")

      dann kommt falsches Ergebnis:
      Inhalt QuellString: abc "def" ghi " jkl
      Inhalt SuchString: "
      Pos: 0

      Ich kann also deinen Fehler nachvollziehen.
    • Ich hole diesen Thread nochmals hoch, nachdem mir heute ein weiterer Fehler mit der Funktion INSTR aufgefallen ist.
      Ich hatte in einem älteren Projekt welches soweit funktionierte Änderungen vorgenommen und nun eben mit der aktuellen BasCom-Version kompiliert.
      Nachdem mir auffiel, dass der oben beschriebene Fehler nun in diesem alten Projekt zugeschlagen hatte, wollte ich den Workaround verwenden.
      Nur funktioniert der bei bei einem Suchstring bestehend aus Chr(13) + Chr(10) bzw. CRLF auch nicht.
      Also hat INSTR auch mit Steuerzeichen im Suchstring ein Problem und liefert selbst wenn der String den Suchstring (welcher eben aus nicht druckbaren Zeichen besteht) enthält den Wert Null zurück.
    • Zitronenfalter wrote:

      Nur funktioniert der bei bei einem Suchstring bestehend aus Chr(13) + Chr(10) bzw. CRLF auch nicht.
      Kleiner Beispielcode (kompilierbar)?

      Ich habe mal ein kleines Testprogramm erstellt:

      BASCOM Source Code

      1. $Regfile = "m8def.dat"
      2. $HWStack = 30
      3. $SWStack = 30
      4. $Framesize = 40
      5. $Crystal = 1000000
      6. Const SuchString = "{013}{010}"
      7. Dim source as String * 20
      8. Source = "Hallo{013}{010}Welt"
      9. Dim Ergebnis as Byte
      10. Do
      11. Ergebnis = Instr(Source , "{013}{010}") ' so geht's nicht
      12. Ergebnis = Instr(Source , SuchString) ' so geht's!
      13. Loop
      Display All
      In der Bascomhilfe steht bei Instr() folgendes:

      Display Spoiler

      No constant can be used for string it must be a string variable.
      Only substr can be either a string or a constant.


      "String" ist hierbei der zu suchende Wert.

      The post was edited 1 time, last by Mitch64 ().

    • Im Grunde könnte man den letzten Post von mir löschen.
      Das Problem konnte ich nämlich jetzt lösen.
      Ich hatte eine lokale Byte-Variable und danach eben die lokale String-Variable deklariert und die zwei Zeichen zugewiesen hatte und dabei übersehen, dass die Byte-Variable in der Folge durch eine Funktion mit einem dWord-Wert mit der Wertigkeit Null belegt wird und somit natürlich den im Speicher darauf folgenden String wieder gelöscht hat.
      Hereingefallen bin ich eben deswegen, dass der alte Code aus IMHO 2019 eben über das im Startthread beschriebene Problem welches erst in der aktuellen BasCom-Version auftritt, gestolpert ist, ich das auf den Workaraund geändert hatte und um diesen String ergänzt habe aber dabei nach der langen Zeit übersehen hatte, dass eine Funktion einen zu "breiten" Wert zurück liefert.
      Somit besteht zwar nach wie vor das im Eingangspost bestehende Problem aber das neue ist eben keines. Da saß der Fehler eindeutig vor dem Schirm :D .