Mid$ Anweisung / Suchfunktion im Board
Mid$ Anweisung / Suchfunktion im Board
Hallo Leute,
mit einigem Erstaunen habe ich festgestellt, dass es in PureBasic offenbar keine Mid$-Anweisung gibt.
Mein Problem ist folgendes:
Ein String fester Länge (Kommandopuffer.s{20000}) wird mit Schleppzeigern Zeichenweise beschrieben / gelesen.
Das Lesen ist mit der MID-Funktion kein Problem aber wie positioniert man ein Zeichen in einem solchen String fester Länge.
Das Einzige was ich hierzu gefunden habe ist eine Prozedur die Strings "zusammenbastelt" was vermutlich irrsinnig langsam ist.
Auch würde mich interessieren warum die Suchfunktion im Board für "mid$", "mid$()" oder auch "mid" keine Ergebnisse liefert obwohl diese
Begriffe im Board enthalten sind.
Gruß
Daffy
mit einigem Erstaunen habe ich festgestellt, dass es in PureBasic offenbar keine Mid$-Anweisung gibt.
Mein Problem ist folgendes:
Ein String fester Länge (Kommandopuffer.s{20000}) wird mit Schleppzeigern Zeichenweise beschrieben / gelesen.
Das Lesen ist mit der MID-Funktion kein Problem aber wie positioniert man ein Zeichen in einem solchen String fester Länge.
Das Einzige was ich hierzu gefunden habe ist eine Prozedur die Strings "zusammenbastelt" was vermutlich irrsinnig langsam ist.
Auch würde mich interessieren warum die Suchfunktion im Board für "mid$", "mid$()" oder auch "mid" keine Ergebnisse liefert obwohl diese
Begriffe im Board enthalten sind.
Gruß
Daffy
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert
Re: Mid$ Anweisung / Suchfunktion im Board
Zur Frage Mid$. Da du fixe Strings benutzt, ists kein Problem mit PokeC ein Zeichen zu ändern. Ungefähr so:
Zur Frage Suchfunktion. Anscheinend funktioniert die Suchfunktion mit Wörtern, deren Länge <= 3 ist, nicht, warum auch immer.
lg Kevin
Code: Alles auswählen
Macro SetChar(_str_, _idx_, _char_)
PokeC(@_str_+SizeOf(Character) * _idx_, _char_)
EndMacro
str.s{5}
str = "Hallo"
SetChar(str, 1, 'b')
Debug str
lg Kevin



http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Re: Mid$ Anweisung / Suchfunktion im Board
Ganz einfach, weil du mind. 4 Zeichen eingeben musst. Ist standardmäßig so beim phpBB-Forum eingestellt. Und Sonderzeichen werden afaik ignoriert bzw. für andere Zwecke verwendet.Daffy0815 hat geschrieben:Auch würde mich interessieren warum die Suchfunktion im Board für "mid$", "mid$()" oder auch "mid" keine Ergebnisse liefert obwohl diese
Begriffe im Board enthalten sind.
Wenn du nach kurzen Suchbegriffen suchen möchtest, dann nutze lieber Google: http://www.google.de/#sclient=psy-ab&hl ... rebasic.fr
- hjbremer
- Beiträge: 822
- Registriert: 27.02.2006 22:30
- Computerausstattung: von gestern
- Wohnort: Neumünster
Re: Mid$ Anweisung / Suchfunktion im Board
Code: Alles auswählen
Structure Zeichen
c.c[0]
EndStructure
fixstring.s{100}
fixstring = "Dies ist ein String mit fester Zeichenlänge"
Debug fixstring
*c.zeichen = @fixstring
*c\c[3] = 65
Debug fixstring
Purebasic 5.70 x86 5.72 X 64 - Windows 10
Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Re: Mid$ Anweisung / Suchfunktion im Board
Vielen Dank für die Hilfe!
Habe die Lösung von CSHW89 verwendet weil sie mir "durchschaubarer" erscheint.
Allerdings habe ich beim Testen im Programm fast in die Tastatur gebissen!
Ich dachte das wenn man einen String fester Länge definiert dieser auch mit der angegebenen Länge angelegt wird.
Dem scheint aber nicht so zu sein.
Mein Pufferstring war immer leer.
Erst als ich diesen mit Zeichen gefüllt hatte stand da auch etwas drin.
Gruß
Daffy
Habe die Lösung von CSHW89 verwendet weil sie mir "durchschaubarer" erscheint.
Allerdings habe ich beim Testen im Programm fast in die Tastatur gebissen!
Ich dachte das wenn man einen String fester Länge definiert dieser auch mit der angegebenen Länge angelegt wird.
Dem scheint aber nicht so zu sein.
Mein Pufferstring war immer leer.
Erst als ich diesen mit Zeichen gefüllt hatte stand da auch etwas drin.
Gruß
Daffy
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert
Re: Mid$ Anweisung / Suchfunktion im Board
Lol, ich find die Lösung von hjbremer eigentlich viel eleganter als meine, würde diese also bevorzugen
. Aber jedem das seine.
lg Kevin

lg Kevin



http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Mid$ Anweisung / Suchfunktion im Board
Ist auch schneller, aber ich denke das wird kaum messbar seinCSHW89 hat geschrieben:Lol, ich find die Lösung von hjbremer eigentlich viel eleganter als meine, würde diese also bevorzugen. Aber jedem das seine.
lg Kevin

PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: Mid$ Anweisung / Suchfunktion im Board
@CSHW89
Also im Prinzip ist die Lösung von hjbremer doch die Gleiche nur das diese "C-mäßig" mit viel "kryptischen" Zeichen versehen ist.
Was passiert ist doch letztendlich nur:
1.) Startadresse des Strings im Speicher ermitteln
2.) Offset addieren
3.) Byte auf Adresse+Offset schreiben
Finde es aber nach wie vor armselig das PureBasic keine MID$-Anweisung eingebaut hat!
Das kann ja sogar mein 89C450-Microcontroller-BASIC seit 20 Jahren (Siehe folgende Zeilen aus dem Handbuch)
MID$() – eine Anweisung zur Zeichenkettenverarbeitung, die einen Teil einer
Zeichenkettenvariable durch eine andere Zeichenkette ersetzt.
Modus: Kommando oder Ablauf
Syntax:
MID$(Zeichenkettenvariable,Beginn[,Länge]) = Zeichenkettenausdruck
· Zeichenkettenvariable ist der Name der Variablen die verändert wird.
· Beginn ist ein numerischer Ausdruck im Bereich 1 bis 254 der die
Zeichenposition markiert ab der die Ersetzung beginnt.
· Länge ist ein numerischer Ausdruck im Bereich 1 bis 254 der die Anzahl
der Zeichen aus Zeichenkettenausdruck angibt mit denen ersetzt wird.
· Zeichenkettenausdruck ist Zeichenkettenkonstante, Zeichenkettenvariable
oder Zeichenkettenfunktion.
Beschreibung:
Die MID$-Anweisung wird zur Ersetzung von Zeichen in einer
Zeichenkettenvariablen durch Zeichen aus einem Zeichenkettenausdruck
verwendet. Ist Beginn größer als die Länge der Zeichenkettenvariable so bleibt
diese unverändert. Wird Länge nicht angegeben wird die Länge von
Zeichenkettenausdruck als Länge angenommen. Unabhängig von den für
Beginn und Länge gewählten Werten wird die Länge der
Zeichenkettenvariablen nicht geändert.
Gruß
Daffy
Also im Prinzip ist die Lösung von hjbremer doch die Gleiche nur das diese "C-mäßig" mit viel "kryptischen" Zeichen versehen ist.
Was passiert ist doch letztendlich nur:
1.) Startadresse des Strings im Speicher ermitteln
2.) Offset addieren
3.) Byte auf Adresse+Offset schreiben
Finde es aber nach wie vor armselig das PureBasic keine MID$-Anweisung eingebaut hat!
Das kann ja sogar mein 89C450-Microcontroller-BASIC seit 20 Jahren (Siehe folgende Zeilen aus dem Handbuch)
MID$() – eine Anweisung zur Zeichenkettenverarbeitung, die einen Teil einer
Zeichenkettenvariable durch eine andere Zeichenkette ersetzt.
Modus: Kommando oder Ablauf
Syntax:
MID$(Zeichenkettenvariable,Beginn[,Länge]) = Zeichenkettenausdruck
· Zeichenkettenvariable ist der Name der Variablen die verändert wird.
· Beginn ist ein numerischer Ausdruck im Bereich 1 bis 254 der die
Zeichenposition markiert ab der die Ersetzung beginnt.
· Länge ist ein numerischer Ausdruck im Bereich 1 bis 254 der die Anzahl
der Zeichen aus Zeichenkettenausdruck angibt mit denen ersetzt wird.
· Zeichenkettenausdruck ist Zeichenkettenkonstante, Zeichenkettenvariable
oder Zeichenkettenfunktion.
Beschreibung:
Die MID$-Anweisung wird zur Ersetzung von Zeichen in einer
Zeichenkettenvariablen durch Zeichen aus einem Zeichenkettenausdruck
verwendet. Ist Beginn größer als die Länge der Zeichenkettenvariable so bleibt
diese unverändert. Wird Länge nicht angegeben wird die Länge von
Zeichenkettenausdruck als Länge angenommen. Unabhängig von den für
Beginn und Länge gewählten Werten wird die Länge der
Zeichenkettenvariablen nicht geändert.
Gruß
Daffy
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert
Re: Mid$ Anweisung / Suchfunktion im Board
Selber basteln hilft...
Vielleicht so...
P.S.
oder so...
Update Unicode
FF 
Vielleicht so...
Code: Alles auswählen
Procedure.s SetMid(String$, StringToSet$, StartPos)
Protected len1, len2, len3
len1 = Len(String$)
len2 = Len(StringToSet$)
len3 = StartPos + len2
If len1 < len3
String$ + Space(len3 - len1)
EndIf
CopyMemory(@StringToSet$, @String$ + StartPos, len2)
ProcedureReturn String$
EndProcedure
a$ = "Hallo unsere Welt ist an ende"
b$ = "unsere Erde"
a$ = SetMid(a$,b$, 6)
Debug a$
oder so...
Update Unicode
Code: Alles auswählen
Procedure HelpSetMid(*String, *StringToSet, StartPos)
Protected len1, len2, len3, *pos, *s1.String, *s2.String
If StartPos < 1
ProcedureReturn #False
EndIf
*s1 = @*String
*s2 = @*StringToSet
len1 = Len(*s1\s)
len2 = Len(*s2\s)
len3 = StartPos + len2
If len1 < len3
len2 = len1 - StartPos
If len2 <= 0
ProcedureReturn #False
EndIf
EndIf
StartPos - 1
CompilerIf #PB_Compiler_Unicode
*pos = StartPos * SizeOf(character) + *String
len2 = len2 * SizeOf(character)
CompilerElse
*pos = StartPos + *String
CompilerEndIf
CopyMemory(*StringToSet, *pos, len2)
ProcedureReturn #True
EndProcedure
Macro SetMid(String, StringToSet, StartPos)
HelpSetMid(@String, @StringToSet, StartPos)
EndMacro
Debug SizeOf(character)
a$ = "Hallo unsere Welt ist an ende"
b$ = "unsere Erde"
Debug SetMid(a$,b$,7)
Debug a$

Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Mid$ Anweisung / Suchfunktion im Board
Hallo Leute,
also irgendetwas stimmt mit der Stringverarbeitung in PureBasic nicht!
Um das zu verdeutlichen habe ich mal 3 lauffähige Beispiele gemacht.
Zum Testen muss über die definierte serielle Schnittstelle (COM1) alle 5 Sekunden die Zeichenkette "DI25=123456<CR>" gesendet werden.
Die empfangene Zeichenkette wird jeweils im Debug-Fenster ausgegeben.
Beispiel 1 ist mit der Variante von CSHW89 realisiert.
Beispiel 2 ist mit der Variante von hjbremer realisiert.
Diese beiden Beispiele verhalten sich völlig gleich.
Irgendwann ist ein empfangenes Zeichen im String nicht mehr vorhanden.
Beispiel 3 ist vom Aufbau her völlig gleich nur das für den Ringpuffer kein String fester Länge sondern ein mit "DIM" dimensioniertes ASCII-Feld verwendet wird.
Und das funktioniert bei gleicher Struktur EINWANDFREI!!!
Würde mich mal interessieren ob ihr den Grund hierfür herausbekommt.
Beispiel 1:
Beispiel 2:
Beispiel 3:
Gruß
Daffy
also irgendetwas stimmt mit der Stringverarbeitung in PureBasic nicht!
Um das zu verdeutlichen habe ich mal 3 lauffähige Beispiele gemacht.
Zum Testen muss über die definierte serielle Schnittstelle (COM1) alle 5 Sekunden die Zeichenkette "DI25=123456<CR>" gesendet werden.
Die empfangene Zeichenkette wird jeweils im Debug-Fenster ausgegeben.
Beispiel 1 ist mit der Variante von CSHW89 realisiert.
Beispiel 2 ist mit der Variante von hjbremer realisiert.
Diese beiden Beispiele verhalten sich völlig gleich.
Irgendwann ist ein empfangenes Zeichen im String nicht mehr vorhanden.
Beispiel 3 ist vom Aufbau her völlig gleich nur das für den Ringpuffer kein String fester Länge sondern ein mit "DIM" dimensioniertes ASCII-Feld verwendet wird.
Und das funktioniert bei gleicher Struktur EINWANDFREI!!!
Würde mich mal interessieren ob ihr den Grund hierfür herausbekommt.
Beispiel 1:
Code: Alles auswählen
#SerialportPLC = 0
#SerialportBaudratePLC = 115200
Global SerialPortNamePLC$ = "COM1"
;
;
#LaengeRegisterKommandoRingpuffer = 30 ;20000
Global RegisterKommandoRingpufferSchreibzeiger.u = 1
Global RegisterKommandoRingpufferLesezeiger.u = 1
Global RegisterKommandoRingpuffer.s{#LaengeRegisterKommandoRingpuffer+1} = Space(#LaengeRegisterKommandoRingpuffer)
Global RegisterKommandoPuffer.s
;
;
Procedure IncRegisterKommandoRingpufferSchreibzeiger()
RegisterKommandoRingpufferSchreibzeiger.u = RegisterKommandoRingpufferSchreibzeiger.u + 1
If RegisterKommandoRingpufferSchreibzeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferSchreibzeiger.u = 1
EndIf
EndProcedure
;
;
Procedure IncRegisterKommandoRingpufferLesezeiger()
RegisterKommandoRingpufferLesezeiger.u = RegisterKommandoRingpufferLesezeiger.u + 1
If RegisterKommandoRingpufferLesezeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferLesezeiger.u = 1
EndIf
EndProcedure
;
;
Macro SetChar(_str_, _idx_, _char_)
PokeC(@_str_+SizeOf(Character) * _idx_, _char_)
EndMacro
;
;
Procedure RegisterEmpfang()
Puffer.b = 0
RegisterEmpfangen.i = #False
If IsSerialport(#SerialportPLC)
While AvailableSerialPortInput(#SerialportPLC) > 0
ReadSerialPortData(#SerialportPLC, @Puffer.b, 1)
EmpfangenesZeichen.s = Chr(Puffer.b)
SetChar(RegisterKommandoRingpuffer.s, RegisterKommandoRingpufferSchreibzeiger.u, Puffer.b)
IncRegisterKommandoRingpufferSchreibzeiger()
If Puffer.b = 13
RegisterEmpfangen.i = #True
Break
EndIf
Wend
If RegisterEmpfangen.i = #True
RegisterKommandoPuffer.s = ""
While RegisterKommandoRingpufferLesezeiger.u <> RegisterKommandoRingpufferSchreibzeiger.u
RegisterKommandoPuffer.s = RegisterKommandoPuffer.s + Mid(RegisterKommandoRingpuffer.s, RegisterKommandoRingpufferLesezeiger.u, 1)
IncRegisterKommandoRingpufferLesezeiger()
Wend
Debug RegisterKommandoPuffer.s
EndIf
EndIf
EndProcedure
If OpenSerialPort(#SerialportPLC, SerialPortNamePLC$, #SerialportBaudratePLC, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
SetSerialPortStatus(#SerialportPLC, #PB_SerialPort_DTR, 0)
EndIf
Quit.i = #False
Repeat
RegisterEmpfang()
;
Until Quit.i = #True
Beispiel 2:
Code: Alles auswählen
#SerialportPLC = 0
#SerialportBaudratePLC = 115200
Global SerialPortNamePLC$ = "COM1"
;
;
#LaengeRegisterKommandoRingpuffer = 30 ;20000
Global RegisterKommandoRingpufferSchreibzeiger.u = 1
Global RegisterKommandoRingpufferLesezeiger.u = 1
Global RegisterKommandoRingpuffer.s{#LaengeRegisterKommandoRingpuffer+1} = Space(#LaengeRegisterKommandoRingpuffer)
Global RegisterKommandoPuffer.s
;
;
Procedure IncRegisterKommandoRingpufferSchreibzeiger()
RegisterKommandoRingpufferSchreibzeiger.u = RegisterKommandoRingpufferSchreibzeiger.u + 1
If RegisterKommandoRingpufferSchreibzeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferSchreibzeiger.u = 1
EndIf
EndProcedure
;
;
Procedure IncRegisterKommandoRingpufferLesezeiger()
RegisterKommandoRingpufferLesezeiger.u = RegisterKommandoRingpufferLesezeiger.u + 1
If RegisterKommandoRingpufferLesezeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferLesezeiger.u = 1
EndIf
EndProcedure
;
;
Procedure RegisterEmpfang()
Structure Zeichen
c.c[0]
EndStructure
;
Puffer.b = 0
RegisterEmpfangen.i = #False
If IsSerialport(#SerialportPLC)
While AvailableSerialPortInput(#SerialportPLC) > 0
ReadSerialPortData(#SerialportPLC, @Puffer.b, 1)
EmpfangenesZeichen.s = Chr(Puffer.b)
*c.zeichen = @RegisterKommandoRingpuffer.s
*c\c[RegisterKommandoRingpufferSchreibzeiger.u] = Puffer.b
IncRegisterKommandoRingpufferSchreibzeiger()
If Puffer.b = 13
RegisterEmpfangen.i = #True
Break
EndIf
Wend
If RegisterEmpfangen.i = #True
RegisterKommandoPuffer.s = ""
While RegisterKommandoRingpufferLesezeiger.u <> RegisterKommandoRingpufferSchreibzeiger.u
RegisterKommandoPuffer.s = RegisterKommandoPuffer.s + Mid(RegisterKommandoRingpuffer.s, RegisterKommandoRingpufferLesezeiger.u, 1)
IncRegisterKommandoRingpufferLesezeiger()
Wend
Debug RegisterKommandoPuffer.s
EndIf
EndIf
EndProcedure
If OpenSerialPort(#SerialportPLC, SerialPortNamePLC$, #SerialportBaudratePLC, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
SetSerialPortStatus(#SerialportPLC, #PB_SerialPort_DTR, 0)
EndIf
Quit.i = #False
Repeat
RegisterEmpfang()
;
Until Quit.i = #True
Code: Alles auswählen
#SerialportPLC = 0
#SerialportBaudratePLC = 115200
Global SerialPortNamePLC$ = "COM1"
;
;
#LaengeRegisterKommandoRingpuffer = 30 ;20000
Global RegisterKommandoRingpufferSchreibzeiger.u = 0
Global RegisterKommandoRingpufferLesezeiger.u = 0
Global Dim RegisterKommandoRingpuffer.a(#LaengeRegisterKommandoRingpuffer+1)
Global RegisterKommandoPuffer.s
;
;
;Hilfsprozeduren
;
Procedure IncRegisterKommandoRingpufferSchreibzeiger()
RegisterKommandoRingpufferSchreibzeiger.u = RegisterKommandoRingpufferSchreibzeiger.u + 1
If RegisterKommandoRingpufferSchreibzeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferSchreibzeiger.u = 0
EndIf
EndProcedure
;
;
Procedure IncRegisterKommandoRingpufferLesezeiger()
RegisterKommandoRingpufferLesezeiger.u = RegisterKommandoRingpufferLesezeiger.u + 1
If RegisterKommandoRingpufferLesezeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferLesezeiger.u = 0
EndIf
EndProcedure
;
;
Procedure RegisterEmpfang()
Puffer.a = 0
RegisterEmpfangen.i = #False
If IsSerialport(#SerialportPLC)
While AvailableSerialPortInput(#SerialportPLC) > 0
ReadSerialPortData(#SerialportPLC, @Puffer.a, 1)
RegisterKommandoRingpuffer.a(RegisterKommandoRingpufferSchreibzeiger.u) = Puffer.a
IncRegisterKommandoRingpufferSchreibzeiger()
If Puffer.a = 13
RegisterEmpfangen.i = #True
Break
EndIf
Wend
If RegisterEmpfangen.i = #True
RegisterKommandoPuffer.s = ""
While RegisterKommandoRingpufferLesezeiger.u <> RegisterKommandoRingpufferSchreibzeiger.u
RegisterKommandoPuffer.s = RegisterKommandoPuffer.s + Chr(RegisterKommandoRingpuffer.a(RegisterKommandoRingpufferLesezeiger.u))
IncRegisterKommandoRingpufferLesezeiger()
Wend
Debug RegisterKommandoPuffer.s
EndIf
EndIf
EndProcedure
If OpenSerialPort(#SerialportPLC, SerialPortNamePLC$, #SerialportBaudratePLC, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
SetSerialPortStatus(#SerialportPLC, #PB_SerialPort_DTR, 0)
EndIf
Quit.i = #False
Repeat
RegisterEmpfang()
;
Until Quit.i = #True
Gruß
Daffy
Wir sind LINUX
Widerstand ist zwecklos - Sie werden emuliert
Widerstand ist zwecklos - Sie werden emuliert