string.insert funzt nicht wenn string=nothing

  • VB.NET
  • .NET 4.5

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    string.insert funzt nicht wenn string=nothing

    Hallo, ich möchte eine Datei als String komplett einlesen, die Daten ergänzen und in eine andere Datei abspeichern. Dazu habe ich zwei Strings definiert, Eingabe- und Ausgabe String, und kopiere Char-weise in den Ausgabe String mit dem Insert-Befehl den Eingabestring. Allerdings bringt VB.Net folgenden Fehler:

    + $exception {"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."} System.NullReferenceException

    Das Coding lautet:

    Public Class Form1
    .
    .
    .
    Public buffer As String
    Public outline As String
    Public inline As String

    Private Sub mvc(ByRef von As String, ByRef nach As String, ByRef posvon As Integer, ByRef posnach As Integer, laenge As Integer)
    For j = 0 To laenge - 1
    nach.Insert(posnach, von.Chars(posvon))
    posnach += 1
    posvon += 1
    Next
    End Sub
    .
    .
    mvc(inline, outline, inpos, outpos, laenge)
    .
    .


    Der Fehler liegt eindeutig daran, dass nach mit Nothing vorbelegt ist. Wie kann man dieses Problem umgehen und in einen leeren String ein Zeichen inserten???
    Vielen Dank
    Richard Bartetzko
    Indem Du vorher ne Überprüfung auf Nothing machst und dann String.Empty zuweist:

    VB.NET-Quellcode

    1. If nach Is Nothing Then nach = String.Empty

    Oder kannst auch mit dem hier arbeiten:

    VB.NET-Quellcode

    1. If nach Is Nothing Then nach = New String


    ##########

    Beachte, dass nach.Insert(posnach, von.Chars(posvon)) keinen sichtbaren Effekt haben könnte und Du evtl. nach = nach.Insert(posnach, von.Chars(posvon)) brauchst.

    Und: Bitte VB.Net-CodeTags benutzen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Danke für die schnelle Antwort. ich habe die String.empty Anweisung eingefügt, aber jetzt kommt folgende Fehlermeldung:

    + $exception {"Das angegebene Argument liegt außerhalb des gültigen Wertebereichs." & vbCrLf & "Parametername: startIndex"} System.ArgumentOutOfRangeException

    nach hat folgenden Wert: Nach ="", aber posnach war 1.

    Richard Bartetzko
    Da String-Indices bei 0 beginnen, sollte klar werden, dass bei einem leeren String nix nach Positionsindex 1 (= nach dem 1. Zeichen) eingetragen werden kann, da ein leerer String keine Zeichen hat. Also ist der korrekte Positionsindex, nach dem man da was einsetzen kann: 0 (null).
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Die Schleife wurde ja einmal durchlaufen und fängt bei 0 an,der pointer war 1 beim Fehler, aber der String war leer. Irgendwie passt da etwas nicht zusammen. Ich möchte ja etwas in der Länge laenge einfügen und die Größe des Strings ist nicht bestimmt. Kann man irgendwie die Länge eines Strings in eine Anweisung vordefinieren oder mit einem Zeichen auffüllen. Ansonsten würde ich sagen hier hat VB eine Schwäche.
    Richard Bartetzko
    Hast Du - wie von mir geschrieben - die eine Codezeile in nach = nach.Insert(posnach, von.Chars(posvon)) geändert? Sonst bleibt nach immer leer. Und dann kommt der Fehler.

    bzw: Deine Variablennamen sind für Außenstehende - zumindest für mich - etwas sehr kryptisch. Wofür steht eigentlich mvc? Was soll die Funktion eigentlich machen, dass mehrere Parameter rein- und wieder rausgegeben werden? Eine Anhängefunktion sollte doch nur einen ByVal-Text bekommen und alles zusammengefügte wiedergeben. Also Function mvc() As String
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Sorry, die Korrektur der Zeile habe ich natürlich vergessen. Jetzt funktionierts.
    Der Befehl mvc kommt aus der Assemblerwelt und bedeutet move charakter. In Analogie dazu habe ich das Unterprogramm danach benannt.
    Da ich die Pointer für die weitere Verarbeitung benötige wird werden die Aufrufparameter modifiziert. Gut der von Parameter müsste nicht mit byval aufgerufen werden.
    Nochmals vielen Dank für die Klärung meines Problems
    Richard Bartetzko

    VB.NET-Quellcode

    1. nach = nach.Substring(0,posnach) + von.Substring(0,laenge) + nach.Substring(posnach)

    (oder so ähnlich)...sollte zum selben Ergebnis führen, jedoch wesentlich performanter, weil du nicht ständig neu allokierst und Daten hin und her schiebst. Du weißt doch bereits die Länge, die eingefügt werden soll, warum dann nicht einmal direkt um diese Länge auffüllen, also auch wenn man das selber schreibt könnte man das ganz anders machen, schließlich sind alle Längen bereits zu beginn bekannt.
    Natürlich musst du dann noch deine Positionen um die länge erhöhen, wenn du die wirklich als Referenzen nutzt, ansonsten benutzt du sowieso zu viele Referenzen. "von" wird z.B. gar nie verändert.

    Zusätzlich würde ich soetwas eher als Funktion mit Rückgabewert machen, als den Inputwert zu verändern, ist besser lesbar und im Sinne von Strings, welche immutable sind sowieso eher vorgesehen.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Das mag ja alles richtig sein, ich habe es mir halt etwas einfach gemacht. Da nicht nur von einer Quelle Daten übertragen werden und die Positionen innerhalb der Datenpuffer erhalten bleiben müssen, schien mir das die einfachste Lösung.
    Danke für den Hinweis
    Richard Bartetzko
    @oobdoo Würde ich mit "Ja" beantworten, ohne mich explizit überzeugt zu haben.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    VB-Fragen über PN / Konversation werden ignoriert!
    Naja es ist trotzdem etwas anderes. string.Empty bekommt vom jitter eine Sonderbehandlung, auch wenn bei einem Vergleich zwischen string.Empty == "" immer true rauskommen wird lässt sich aus der jitter Sonderbehandlung schließen, dass durch string.Empty gewisse Vorteile Vorhanden sein können, vermutlich was Codeerzeugung und Optimierung anbelangt. Also einfach immer string.Empty verwenden...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    https://referencesource.microsoft.com/#mscorlib/system/string.cs schrieb:


    // The Empty constant holds the empty string value. It is initialized by the EE during startup.
    // It is treated as intrinsic by the JIT as so the static constructor would never run.
    // Leaving it uninitialized would confuse debuggers.
    //
    //We need to call the String constructor so that the compiler doesn't mark this as a literal.
    //Marking this as a literal would mean that it doesn't show up as a field which we can access
    //from native.
    public static readonly String Empty;


    IL ist nicht alles was sagt wie etwas funktioniert.

    Am besten Sichtbar hier:
    referencesource.microsoft.com/…tions.cs,d8f38cb9ecc52554
    IsHardwareAccelerated ist nicht immer false, es wird vom JIT einmalig angepasst abhängig davon ob der SIMD unterstützt wird oder nicht. Obwohl im Code davon nichts wirklich Sichtbar ist bis auf das JitIntrinsicAttribute. Aber der Code der das behandelt geht einfach fest nach dem Namen der Klasse und Property um dieses anzupassen. Das Attribut ist dabei nur ein Indiz für den Programmierer...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---