Wie werden ANSI Strings gesplittet?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    Wie werden ANSI Strings gesplittet?

    NAbend,
    hab da ein Problem beim splitten eines ANSI-Strings.

    VB.NET-Quellcode

    1. .Split(New String() {" "}, StringSplitOptions.RemoveEmptyEntries)

    von "Test0 Test1 Test2" wird nur "Test0" in das String-Array übergeben und der Rest komplett Ignoriert.
    Woran kann das liegen ?
    Das Chaos beginnt mit komprimierter Ordnung (Steppenpferd 2019)
    Das liegt an falschen Voraussetzungen, die Du uns wohl verschweigst.
    Bilder
    • CorrectSplit.png

      9,43 kB, 634×137, 87 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Klasse:

    VB.NET-Quellcode

    1. Public Shared Function ReadSections() As String
    2. Dim ptr As IntPtr = Marshal.StringToHGlobalAnsi(New String(CChar(String.Empty), 1024))
    3. Dim len As Int32 = GetPrivateProfileSectionNames(ptr, 1024, iniFile)
    4. Dim buff As String = Marshal.PtrToStringAnsi(ptr, len)
    5. Marshal.FreeHGlobal(ptr)
    6. Return buff
    7. End Function

    Form1:

    VB.NET-Quellcode

    1. Dim words As String() = ReadSections().Split(New String() {" "}, StringSplitOptions.RemoveEmptyEntries)
    Das Chaos beginnt mit komprimierter Ordnung (Steppenpferd 2019)
    Interessant. Naja, eigentlich nicht. Denn ich hatte mit meinem Screenshot bewiesen, dass der Code funktioniert wie erwartet. Was nun in Deiner ini-Datei steht, weiß ich nicht. Aber Du solltest prüfen, was wirklich bei ReadSections rauskommt, bevor Du es splittest. Test0-Leerzeichen-Test1-Leerzeichen-Test2 ist es offensichtlich nicht. Sonst würde der Code ja laufen, wie Du meinem Screenshot entnehmen kannst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Steppenpferd

    Es ist schon so. Überzeuge dich das die static Funktion ReadSections auch wirklich den gewünschten String in dem Format wie due es wünscht zurückgibt. Ich hab auch schon erlebt, dass mit dieser vorgehendsweise der Zeiger ptr abreisst, und am Schluss der String nicht mehr in dieser Quali vorhanden ist.
    Der String an sich, scheint richtig wiedergegeben zu werden. Ich vermute es liegt am Leerzeichen. Teste es grade

    Edit: jup das wars und so läufts prima

    Und der Vollständigkeit halber:
    Die Funktion ließt alle Sektions-Titel einer x-Beliebigen *.ini Datei auf einmal aus.

    Klasse:

    VB.NET-Quellcode

    1. Public iniFile As String = "filename.ini"

    Form1:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim words() As String = ReadSections().Split(New String() {CChar(String.Empty)}, StringSplitOptions.RemoveEmptyEntries)
    3. For Each word As String In words
    4. ListBox1.Items.Add(word)
    5. Next
    6. End Sub

    Das Chaos beginnt mit komprimierter Ordnung (Steppenpferd 2019)

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „Steppenpferd“ ()

    Ich mache das noch gerne mit dem StringBuilder

    Freundliche Grüsse

    exc-jdbi

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System.Text
    4. Imports System.Runtime.InteropServices
    5. Module Module1
    6. Sub Main()
    7. Dim section, key As String
    8. Dim filename As String = "..\..\data.ini"
    9. Dim data As New List(Of String())
    10. key = String.Format("data{0}", 0)
    11. section = String.Format("Section{0}", 0)
    12. data.Add(DllHelpers.ReadSections(filename, section, key) _
    13. .Split(New String() {" "},
    14. StringSplitOptions.RemoveEmptyEntries))
    15. For i As Int32 = 0 To 1
    16. key = String.Format("data{0}", i)
    17. section = String.Format("Section{0}", i)
    18. data.Add(DllHelpers.ReadSections(filename, section, key) _
    19. .Split(New String() {" "},
    20. StringSplitOptions.RemoveEmptyEntries))
    21. Next
    22. Stop
    23. End Sub
    24. End Module
    25. Public Class DllHelpers
    26. <DllImport("kernel32.dll")>
    27. Public Shared Function GetLastError() As UInteger
    28. End Function
    29. <DllImport("kernel32.dll", SetLastError:=True)>
    30. Public Shared Function GetPrivateProfileString(ByVal lpAppName As String,
    31. ByVal lpKeyName As String,
    32. ByVal lpDefault As String,
    33. ByVal lpReturnedString As StringBuilder,
    34. ByVal nSize As Int32,
    35. ByVal lpFileName As String) As Int32
    36. End Function
    37. Public Shared Function ReadSections(filename As String,
    38. section As String,
    39. key As String) As String
    40. Dim sb = New StringBuilder(1024)
    41. Dim length As Integer = GetPrivateProfileString(section,
    42. key,
    43. String.Empty,
    44. sb,
    45. sb.Capacity,
    46. filename)
    47. If length = 0 Then
    48. Console.WriteLine(GetLastError.ToString) : Return Nothing
    49. End If
    50. Return sb.ToString
    51. End Function
    52. End Class
    Dateien
    • ConsoleApp1.zip

      (9,67 kB, 67 mal heruntergeladen, zuletzt: )
    Jo den verwende ich auch schon mal und MS sagt dazu...
    Obwohl die StringBuilder-Klasse im Allgemeinen eine bessere Leistung als die String-Klasse bietet, sollten Sie String nicht automatisch durch StringBuilder ersetzen, wenn Sie Zeichenfolgen bearbeiten möchten. Die Leistung hängt von der Größe der Zeichenfolge, der für die neue Zeichenfolge zuzuweisenden Speichermenge, dem System, auf dem Ihre App ausgeführt wird, und der Art der Operation ab. Sie sollten darauf vorbereitet sein, Ihre App zu testen, um festzustellen, ob StringBuilder tatsächlich eine erhebliche Leistungsverbesserung bietet.
    Das Chaos beginnt mit komprimierter Ordnung (Steppenpferd 2019)
    Was absolut berechtigt ist.

    In einer ini-Datei sollten auch die Informationen, die man sich so holen will kurz sein.

    GetPrivateProfileString ist nicht dafür gedacht, extrem lange Strings aus der ini-Datei bereitzustellen. Dafür gibt es dann andere Möglichkeiten.

    Freundliche Grüsse

    exc-jdbi