Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Einen String in einen Buffer kopieren ?
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
arduno



Anmeldungsdatum: 12.05.2011
Beiträge: 252

BeitragVerfasst am: 20.08.2016, 12:26    Titel: Einen String in einen Buffer kopieren ? Antworten mit Zitat

Hallo, guten Tag.
Wie kann ich bitte einen String in einem Buffer kopieren?
Code:

Dim AS string text
buffer = ALLOCATE( 1000 )

text="hallo"
.....


Danke.
GRuss
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 20.08.2016, 15:25    Titel: Antworten mit Zitat

Die Adresse des String-Inhalts bekommst du mit STRPTR. Den kannst du z. B. mit der CRT-Funktion memcpy in den anderen Speicherbereich rüberkopieren (damit habe ich selbst noch nie gearbeitet, aber schon ein paar Mal ein Beispiel im Forum gesehen; die Syntax findest du hier, und die Funktion steht in der crt/string.bi).

Natürlich kann man auch Byte für Byte rüberschieben:
Code:
for i as integer = 0 to len(text)-1
  buffer[i] = text[i]
next


Dann sollte buffer ein BYTE PTR sein.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1874
Wohnort: D59192

BeitragVerfasst am: 20.08.2016, 15:37    Titel: Antworten mit Zitat

oder
Code:
CopyMemory(buffer, @text, Sizeof(text))

_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 20.08.2016, 16:00    Titel: Antworten mit Zitat

Wirklich @text oder STRPTR(text)?
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
arduno



Anmeldungsdatum: 12.05.2011
Beiträge: 252

BeitragVerfasst am: 20.08.2016, 17:18    Titel: Antworten mit Zitat

Hallo danke für die Info.

Das funktioniert jetzt.

Gruss

Code:

#Include "windows.bi"
#Include "fbgfx.bi"
#include "vbcompat.bi"
Using FB

Dim as HANDLE hMap
Dim Shared As Integer zahl
Dim Shared As String text
Dim AS byte PTR buffer
buffer = ALLOCATE( 1000 )

screenres 320,200,32,1,4
WindowTitle "filemap-send"
ScreenControl SET_WINDOW_POS, 50, 40

hMap = CreateFileMapping( cast(HANDLE,INVALID_HANDLE_VALUE), _
                          null, _
                          PAGE_READWRITE, _
                          0, _
                          1000, _
                          "MyFileMapping" )
buffer = MapViewOfFile( hMap, _
                       FILE_MAP_ALL_ACCESS, _
                       0, _
                       0, _
                       0 )

Do
  text="stringtest, es geht..."
  CopyMemory(buffer, STRPTR(text), len(text))
  Locate 3,1,1
  Print "sende text"
  Sleep 300
loop Until inkey = chr(27)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 20.08.2016, 20:11    Titel: Antworten mit Zitat

Es geht auch ohne Bibliotheken, nur mit FB - Bordmitteln:
Code:
Dim As Byte Ptr buffer = Callocate(1000)
Dim As String text = "Hallo Welt"

For x As Integer = 0 To Len(text) - 1
   buffer[x] = text[x]
Next

'zur kontrolle
For x As Integer = 0 To Len(text) + 5
   Print buffer[x],Chr(buffer[x])
Next

DeAllocate buffer

Sleep

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 21.08.2016, 03:26    Titel: Antworten mit Zitat

grindstone hat Folgendes geschrieben:
Es geht auch ohne Bibliotheken, nur mit FB - Bordmitteln [...]
Ich würde memcpy aus der CRT verwenden, die ist ebenfalls so-und-so bei FB dabei. Beispiel (ungetestet):
Code:
#include "crt.bi"
dim a as string = "Hallo Welt"
dim b as zstring ptr = allocate(len(a)+1)
memcpy(b, strptr(a), len(a)+1)
'....
deallocate(b)


@ funktioniert übrigens bei Stringkonstanten (z.B. @"Hallo"), so meine bisherige Erfahrung. Zur Sicherheit würde ich allerdings überall strptr verwenden. Bei String variablen ist es auf jeden Fall notwendig, da @ hier die Adresse des String Descriptor zurückgibt, nicht die der String Daten.
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Elor



Anmeldungsdatum: 12.07.2013
Beiträge: 205
Wohnort: Konstanz

BeitragVerfasst am: 21.08.2016, 10:25    Titel: Antworten mit Zitat

Könnte man buffer nicht auch einfach als ZSTRING Deklarieren?
Beispiel:
Code:

Dim As String Text
Dim As Zstring* 1000 buffer

  Text= "Das ist ein String“
  buffer= Text

  Print buffer
  Print buffer[0], Chr (buffer[0]
  Print SizeOf (buffer)
  Print @buffer

Zum löschen des buffers würde ich dann Clear verwenden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 21.08.2016, 12:15    Titel: Antworten mit Zitat

Zitat:
Könnte man buffer nicht auch einfach als ZSTRING Deklarieren?
Ja, kann man. Das dürfte sogar die einfachste Lösung sein, die allerdings ihre Tücken hat:
Code:
Dim As ZString * 1000 buffer
Dim As ZString * 1000 b2

buffer = "123" + Chr(0) + "456"

Print Len(buffer), buffer
Print
For x As Integer = 0 To 8
   Print buffer[x],Chr(buffer[x])
Next

b2 = buffer
Print
Print Len(b2), b2
Print
For x As Integer = 0 To 8
   Print b2[x],Chr(b2[x])
Next

Sleep


Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Elor



Anmeldungsdatum: 12.07.2013
Beiträge: 205
Wohnort: Konstanz

BeitragVerfasst am: 21.08.2016, 17:47    Titel: Antworten mit Zitat

grindstone hat Folgendes geschrieben:

… , die allerdings ihre Tücken hat:

Stimmt, die Tücken gibt es. Aber wer sich mit Null Terminierten Strings auskennt kämme nie auf die Idee, zwei String teile durch Null getrennt aneinander hängen zu wollen. Wer das tut, darf sich nicht wundern wenn er nur den ersten Textteil zu sehen bekommt.
Ich bin jetzt einfach davon ausgegangen das arduno einen String zur weiteren Verarbeitung als Null terminierten String benötigt.
Wenn er aus einer Funktion einen ZString zurück erhält, kann er diesen problemlos in einen String zurück kopieren.
Die verschiedenen Print-Varianten in meinem Beispiel waren ja nur so ein Hinweis darauf, wie ein ZString-Type möglicherweise angesprochen werden könnte.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 21.08.2016, 19:42    Titel: Antworten mit Zitat

Elor hat Folgendes geschrieben:
...wer sich mit Null Terminierten Strings auskennt kämme nie auf die Idee, zwei String teile durch Null getrennt aneinander hängen zu wollen.
Das hatte ich damit auch nicht gemeint. Solange man mit reinem Text arbeitet, dürfte es keine Probleme geben. Aufpassen muß man aber, wenn man auf diese Weise auch allgemeine Daten übertragen möchte, in denen durchaus Nullbytes vorkommen können. Denn dann liefert
    1) Len(..) mit hoher Wahrscheinlichkeit falsche Werte zur Datenmenge und es wird
    2) beim eventuellen Umkopieren als String alles nach dem ersten Nullbyte abgeschnitten.
Siehe dazu auch https://forum.qbasic.at/viewtopic.php?t=8751

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 23.08.2016, 08:11    Titel: Antworten mit Zitat

[ENTFERNT] (Dämlicher Denkfehler) grinsen


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]


Zuletzt bearbeitet von ThePuppetMaster am 24.08.2016, 08:38, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 23.08.2016, 10:05    Titel: Antworten mit Zitat

Wenn LEN(txt) = 0, dann geht die Schleife von 0 bis -1 (STEP 1), wird also nicht durchlaufen.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Elor



Anmeldungsdatum: 12.07.2013
Beiträge: 205
Wohnort: Konstanz

BeitragVerfasst am: 23.08.2016, 12:31    Titel: Antworten mit Zitat

@grindstone: Das es diese Tücken gibt die du da ansprichst weiß ich schon, deshalb hab ich ja auch auf die Referenz verlinkt. Da ist das ja alles recht gut beschrieben. Da arduno einen String in einen uByte Puffer kopiert und laut Referenz der ZString-Type als solcher verwendet werden kann, schien mir dieser Datentype als geeignet.
Eine Anmerkung vielleicht noch:
Mit Len lässt sich ja die Anzahl der gespeicherten Zeichen bis zum Auftreten eines Chr(0) Zeichens ermitteln. Wenn man jetzt aber doch mehrere Strings durch 0 getrennt speichern will, geht das auch. Man muss jetzt aber die Variable selber auslesen und dabei die gesamt Länge beachten. Die lässt sich mit SizeOf (VarName) auslesen was meines Wissens mit einem uByte Ptr nicht möglich ist.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 23.08.2016, 15:39    Titel: Antworten mit Zitat

Vorsicht: SIZEOF(ZSTRING*anzahl) ist immer anzahl, egal wie viel du in den ZSTRING hineinspeicherst (und das kann deutlich weniger sein, als "hineinpasst"). SIZEOF(ZSTRING PTR) ist dagegen immer 4 oder 8, so groß wie ein PTR halt gerade ist.

Einen Nachteil sehe ich an ZSTRINGs fester Größe ja schon, nämlich dass sie eine feste Größe besitzen. Man kann sie nicht eben mal löschen oder vergrößern, wenn der Bedarf dazu gegeben ist.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Elor



Anmeldungsdatum: 12.07.2013
Beiträge: 205
Wohnort: Konstanz

BeitragVerfasst am: 23.08.2016, 17:30    Titel: Antworten mit Zitat

nemored hat Folgendes geschrieben:

Vorsicht: SIZEOF(ZSTRING*anzahl) ist immer anzahl, egal wie viel du in den ZSTRING hineinspeicherst (und das kann deutlich weniger sein, als "hineinpasst"). SIZEOF(ZSTRING PTR) ist dagegen immer 4 oder 8, so groß wie ein PTR halt gerade ist.

Genau so ist es, anders kann der ZString gar nicht durchsuchen werden. Nehmen wir mal als Beispiel den 1000er Buffer
Code:

Dim As Zstring* 1000 Buffer

und als weiteres das Beispiel von grindstone in dem er zwei Strings in den Buffer schreibt.
Code:

buffer = "123" + Chr(0) + "456"

Es könnten aber noch mehr Strings hintereinander geklebt sein. Um diese auszulesen muss ich jetzt selber nach den NULLEN suchen, alles was dazwischen liegt sind (unterstellen wir einfach) gültige Zeichen. Wenn ich auf eine NULL treffe, ist ein String zu ende und der Index muss um eins erhöht werden. Jetzt muss ich ja prüfen ob ich weiter lesen darf (Index >= SizeOf (Buffer)- 1) oder nicht. Deshalb der Hinweis auf auf SIZEOF.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 23.08.2016, 18:32    Titel: Antworten mit Zitat

Ich sehe da gerade den Vorteil nicht. Wenn ich weiß, dass ich einen ZSTRING*1000 verwenden will, muss ich die Größe nicht mit SIZEOF überprüfen, sie wird 1000 sein (bzw. 999 + Nullbyte). Das kann ich bei ALLOCATE(1000) genauso merken. Wenn ich den ZSTRING*1000 aber z. B. als Parameter übergebe (also an eine Stelle, wo seine Länge nicht mehr bekannt sein muss), ist SIZEOF sowieso "kaputt". Dann musst du bei Bedarf die Länge auch wieder gesondert übergeben.


Mal zur Verdeutlichung, was ich meine:
Code:
sub testsub(testvar as zstring)
  print "SIZEOF: " & sizeof(testvar)
  print "LEN:    " & len(testvar)
  print "value:  " & testvar
end sub

dim as zstring*99 testvar = "abc"
testsub(testvar)

_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 23.08.2016, 19:19    Titel: Antworten mit Zitat

@Elor: Ich fürchte, du verstehst mich immer noch miss.

Meine Absicht ist es nicht (ich wiederhole: nicht), zwei Textabschnitte mit einem Nullbyte zu verbinden. Betrachte die "123" und "456" einfach als Synonyme für "beliebige 8-Bit-Werte zwischen 1 und 255". Ich habe diese Methode nur benutzt, weil es die einfachste Mögklichkeit ist, entsprechende Werte in den Puffer hineinzuschreiben.

Nochmal: Bei Verwendung von reinem Text gibt es keinerlei Probleme. Len(...) liefert den korrekten Wert und beim Kopieren von String zu String verschwinden keine Daten. Probleme treten erst auf, wenn man versucht, die so programmierte Übertragungsroutine irgendwann einmal (in einigen Monaten oder Jahren) auch für die Übertragung beliebiger Daten (Messwerte, Bilder, Programmcode etc.) zu benutzen. Ich bin nämlich (siehe o.a. Link) vor kurzem selbst in diese Falle getappt:
    Herunterladen von HTML-Text --> keine Probleme
    Herunterladen von mp4 - Videos --> Abbruch nach wenigen Bytes
Hinter der Ursache habe ich fast 2 Tage hergesucht.

nemored hat Folgendes geschrieben:
Mal zur Verdeutlichung, was ich meine: ...
Zur Ergänzung: Bei "nomalen" Strings sieht es wieder anders aus. SizeOf(...) ist immer 12, dafür hat Len(...) den korrekten Wert, und der Stringinhalt wird komplett übertagen:
Code:
Sub testsub(testvar As String)
  Print "SIZEOF: " & SizeOf(testvar)
  Print "LEN:    " & Len(testvar)
  Print "value:  " & testvar
End Sub

Dim As String testvar = "abc"+Chr(0)+"123"
testsub(testvar)

Sleep


Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 23.08.2016, 20:02    Titel: Antworten mit Zitat

Wenn ich mich nicht täusche müsste SIZEOF(STRING) = 3*SIZEOF(ANY PTR) sein (also 12 bei 32bit und 24 bei 64bit).

Um die ganze Diskussion (hoffentlich) ein bisschen zu entwirren: ZSTRING kann durchaus als Byte-Puffer verwendet werden, nur ist die Kopie des Speicherbereichs in einen anderen in aller Regel nicht mit einer einfachen Zuweisung zstring1 = zstring2 möglich. Mit Funktionen wie memcpy oder copyMemory ist das dagegen genauso gut möglich wie mit einem allozierten Byte-Puffer - die Anzahl der zu kopierenden Byte muss ja angegeben werden.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 129
Wohnort: Opel Stadt

BeitragVerfasst am: 24.08.2016, 14:57    Titel: Antworten mit Zitat

Wie bekomme ich einen Hex String, z.B. ein PNG Bild als Binär Daten abgespeichert, im Speicher gespeichert, um das Bild später mit GDI+ zu streamen?

Code:
Function PNG_Image() As String
   Dim PNG_Image_String As String
   PNG_Image_String = "&h89504E470D0A1A0A000..."
   PNG_Image_String &= "2C6E2B24704660BF01603D22F...
   Return PNG_Image_String
End Function

_________________
Gruß,
UEZ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz