Fehler, Irrtümer, Fragen - Seite 2576

 
Vict:

Deine Beispiele sind lustig, du hast alles entfernt, du hast UB (String Literal Modification) gelassen, und jeder muss telepathieren. Wenn Sie einen klugen Ratschlag erwarten, geben Sie ein Minimum an funktionierendem Code (auf zwei Seiten), sonst ist es einfach nur Müll.

Das Beispiel zeigt die Stelle, die das Problem verursacht, d.h. das Problem liegt im Kopieren des wchar_t*-Zeigers in den mql-String.
Der Rest des Codes ist für das Problem nicht relevant und nicht nützlich, da er nur prüft, ob Daten vorhanden sind, dann liest usw.
Warum sollte man es in das Beispiel schreiben und den Kern des Problems verunreinigen, wenn selbst bei vereinfachtem Code viele Leute nicht verstehen, was das Problem ist.
getData() ist eine Netzwerkfunktion, die FrameOpcodeliest und die empfangenen Daten als Zeiger auf eine Zeichenkette vom Typ const wchar_t * zurückgibt.

Jeder weiß, dass die einfache Funktionwcscpy(out, data) dieZeichenkette const wchar_t * in dieZeichenkettewchar_t *kopiert und automatisch die Länge der Zeichen bis zur Endstelle null const wchar_t * zählt.
Hier stoßen wir auf einen Fehler, mql string akzeptiert nicht korrekt einekopierte Zeichenkettewchar_t *, also warum? Wenn die Funktion das Terminal automatisch als Null erkennt.
In Renats Artikel werden Strings über memcpy mit Bytegrößenfehler kopiert. Vielleicht wird derselbe Ansatz im Terminalcode selbst verwendet, um einen String vom Typ mql zu bilden.
Wie Sie sehen,
istmemcpy nicht nur nicht für das Kopieren von Strings geeignet, sondern führt auch bei einem Größenfehler der übergebenen Bytes zu gezackten Daten.
Es gibt noch weitere spezielle C-Funktionen zum Kopieren von Zeichenketten, z. B.wcscpy, wcsncpy usw.
Und Renat selbst schrieb in einem der Threads, dass bald komplett überarbeitet werden mit Strings arbeiten, offenbar das Problem bekannt ist, aber aus irgendeinem Grund Schweigen als Reaktion auf das Problem, das ich angegeben haben.

Hier ein Vergleich der Bytegröße vonwchar_t*-Zeigern und dem einfachen Typwchar_t

Dateien:
1.PNG  83 kb
 
Roman:

Natürlich ist es einfacher, ein ganzes Durcheinander als Antwort zu schreiben als einen normalen reproduzierbaren Test, indem man getData() durch etwas ersetzt. Was erwarten Sie, wenn UB auf UB und die Schlussfolgerungen falsch sind:

memcpy(cp,to,wcslen(to)*sizeof(wchar_t));  //в этой строке должен быть указатель sizeof(wchar_t *)

alles ist da. Irgendetwas stimmt nicht mit Ihren Vorstellungen über Saiten, daher die Zersiedelung.

 
Vict:

Natürlich ist es einfacher, ein ganzes Durcheinander als Antwort zu schreiben als einen normalen reproduzierbaren Test, indem man getData() durch etwas ersetzt. Was erwarten Sie, wenn UB auf UB und die Schlussfolgerungen falsch sind:

alles ist da. Irgendetwas stimmt mit Ihren Vorstellungen von Zeichenketten nicht, daher die Fehler.

Es gibt keine Möglichkeit, reproduzierbaren Code bereitzustellen, da Sie selbst wissen, dass es sich um eine DLL handelt, die Bibliotheken von Drittanbietern verwendet.
Deshalb dachte ich, dass im Beispiel ein Fehler vorliegt.
memcpy(cp,to,wcslen(to)*sizeof(wchar_t));//Diese Zeichenkette muss den Zeiger sizeof(wchar_t *) enthalten

Wenn wir die Funktion ohne den Zeiger verwenden,

memcpy(out, data, wcslen(data) * sizeof(wchar_t));

führt dazu, dass das Ende der Zeichenkette mit unnötigen Zeichen überfrachtet wird. Sehen Sie sich das Ende der Zeichenkette im Bild an.
Und es ist logisch, dass, wenn wir einen String wchar_t * als Zeiger kopieren, wir die Größe des Zeigers und nicht die Größe des Typs übergeben sollten.

Und wenn wir einen Zeiger verwenden,

memcpy(out, data, wcslen(data) * sizeof(wchar_t*));

die Zeichenfolge ist eindeutig und ohne zusätzliche Zeichen.
Es würde nichts ausmachen, aber in beiden Fällen habe ich weitere Probleme mit dem Parsing, d.h. Strings lecken und werden übersprungen.

Und wenn ich diese Funktion verwende, dann läuft nichts aus, das Parsing ist gut, nur ein zusätzliches Zeichen am Ende des Zeilenumbruchs, dann erscheint es und verschwindet dann wieder.

wcsncpy(out, data, wcslen(data));

Also gehe ich durch eine Reihe von Optionen, aber mit memcpy ohne Zeiger auf sizeof, das Ergebnis kann im Screenshot gesehen werden.

Ich möchte empfangene wchar_t * String für Terminal Null überprüfen, ob es vorhanden ist oder nicht.
Wie lässt sich das bewerkstelligen?

Dateien:
 
Verwendung einer Funktion ohne Zeiger,

es ohne \0 am Ende auslässt.

Und wenn ich einen Zeiger verwende,

hier sind Sie außer Rand und Band

Und wenn ich diese Funktion verwende, dann läuft nichts aus, alles wird gut geparst, nur ein zusätzliches Zeichen am Ende der Zeichenfolge, es erscheint und verschwindet.

ohne \0 wieder heraus. Siehe Dokumente

wcsncpy, wcsncpy_s

...

Wenn count erreicht ist, bevor die gesamte Zeichenkette src kopiert wurde, ist das resultierende breite Zeichenfeld nicht null-terminiert.

...

HH: vielleicht gar nicht mit Strings? speichern Sie Arrays in wchar_t und führen Sie sie aus, und innerhalb von µl konvertieren in String, wenn nötig https://www.mql5.com/ru/docs/convert/shortarraytostring

 
Vict:

ZS: vielleicht nicht durcheinander mit Zeichenfolgen überhaupt? speichern Sie Arrays in wchar_t und führen Sie sie, und innerhalb der µl konvertieren in String, wenn nötig

Oh, danke )), für den Hinweis, dass wcsncpy die Null abschneidet.
Ja Arrays sind für letzte links, wenn Zeiger nicht funktionieren, ich werde Arrays verwenden.

 

Die Forum-Engine erlaubt es nicht, einen Beitrag aus einem einzigen Bild zu erstellen. Erfordert die Eingabe von Text.

Sie müssen ein Leerzeichen setzen.

 
fxsaber:

Die Forum-Engine erlaubt es nicht, einen Beitrag aus einem einzigen Bild zu erstellen. Erfordert die Eingabe von Text.

Ich muss ein Leerzeichen setzen.

Das scheint sinnvoll zu sein: Dies ist ein Forum und die Hauptsache ist der Text. Ein Bild beigefügt, wie viel zu einer Zeit. Dies ist kein Bilderfriedhof.

 

Ich habe den Code fertig, es funktioniert in MT4/5, aber ich habe eine kleine Überraschung

Wie kann ichTesterStop() in MQL4 ersetzen?

?

 
Igor Makanu:

Wie kann ich TesterStop() in MQL4 ersetzen?

ExpertRemove.

 
fxsaber:

ExpertRemove.

Ich kenne diese Variante, aber ich habe Berichte gesehen, dass ExpertRemove(0) nicht für Expert Advisors im Markt verwendet werden kann.

Im Allgemeinen verwende ich TesterStop() in zwei Fällen:

- anstelle von INIT_PARAMETERS_INCORRECT, um das Protokoll des Optimierers zu verbergen

- Wenn nicht genügend Mittel vorhanden sind, um einen Auftrag zu eröffnen, eröffne ich ihn nicht, sondern schließe den Test, um ihn schneller zu optimieren.