PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dem Escapezeichen escape escapen :D


buckelflips
2017-05-22, 09:36:56
Ich bin auf der Suche (in meinem Fall C#, aber ich denke das ist in den meisten Programmiersprachen so)

Wenn ich einen String schreibe
"ABCDEF \t GHIJKL \n MNOPQRS..."
Dann macht die Ausgabe bei "\t" einen Tab und bei "\n" eine neue Zeile usw.
Die Zeichen sollten bekannt sein.

Wenn ich jetzt einen UserInput erwarte und der User
ABCDEF \t GHIJKL \n MNOPQRS... eingibt
Dann werden die Escapezeichen escaped, oder ignoriert, oder was auch immer.

Meine Frage ist. Wer macht das? Das Terminal? oder ist die Methode so implementiert? In meinem Fall Console.Writeline();

Kann man sich generell die Standardimplementierungen irgendwie anschauen?

Mir geht’s hier nicht um einen Workaround. Ich will wissen wie das funktioniert.

Monger
2017-05-22, 11:09:58
Escapen und Unescapen ist tatsächlich hochspezifisch, je nach Programmiersprache. Allein in C# gibt es mindestens mal drei Varianten wie String Literale escaped (oder halt nicht) werden, deshalb kommt es da jetzt sehr genau darauf an, was genau du gemacht hast.
Was die Konsole dann daraus macht, ist auch nochmal eine völlig andere Geschichte.

Kannst du mal ein Codebeispiel schreiben? Der Code vom .NET Framework ist größtenteils öffentlich, daher kann man da tatsächlich wahrscheinlich in die Implementierung reingucken.

Aber sieh mal hier:
https://msdn.microsoft.com/de-de/library/xf2k8ftb(v=vs.110).aspx

Die Konsole behandelt Sonderzeichen in der Tat speziell. Gibt mehrere Überladungen für Writeline bzw. Einstellungen dafür.

Monger
2017-05-22, 12:08:22
Um mal bei deinem Beispiel zu bleiben: \t bzw. \n werden in einem "normalen" C# String in die jeweiligen UTF-8 Zeichen aufgelöst. Da das Steuerzeichen sind, gibt es keine visuelle Repräsentation davon. Die Konsole stellt diese folgerichtig nicht da. Das ist mit ein Grund, weshalb es evtl. keine gute Idee ist, Textinhalte von A nach B über die Konsole zu transportieren: man müsste unzählige Male hin und hercodieren.

Wenn du genau diese Folge darstellen willst, musst du entweder deine Escape Zeichen escapen:

"ABCDEF \\t GHIJKL \\n MNOPQRS..."


Oder in C# das String Literal verwenden was automatisch alles escaped:

@"ABCDEF \t GHIJKL \n MNOPQRS..."

buckelflips
2017-05-22, 12:20:16
Ich nehm jetzt einfach mal
string s, hCoded;

hCoded = "Ein normaler String mit \n Escape Zeichen";
s = Console.ReadLine();

Console.WriteLine(hCoded);
Console.WriteLine(s);

hCoded macht jetzt den normalen Zeilenumbruch. Wenn ich genau das selbe als selbe als User eingebe behandelt er das "\n" nicht als newLine sondern als normale Zeichen.

Das ich aber mit NewLine das Neue Zeile neu definieren kann ist interessant. Über das Visual Studio Definition einsehen habe ich mich nach sowas blöd gesucht.

Monger
2017-05-22, 15:16:24
Die Konsole kennt die Escape Sequenzen von C# natürlich nicht. Dort müsstest du wahrscheinlich direkt den ASCII/UTF-8 Code eingeben (17 für \n, iirc), damit es in deiner Anwendung auch so ankommt.

In der Praxis ist sowas natürlich hakelig. Über Readline Sonderzeichen einzulesen ist nicht so super. Du könntest natürlich Readline mehrfach aufrufen, und so Zeile für Zeile reinpumpen, bis du z.B. nur noch eine leere Zeile bekommst.

Abnaxos
2017-05-22, 21:48:57
Meine Frage ist. Wer macht das? Das Terminal? oder ist die Methode so implementiert? In meinem Fall Console.Writeline();
Normalerweise macht das der Compiler, wenn er das String-Literal übersetzt. Im übersetzten Code steht dort kein "\n" mehr, sondern tatsächlich ein Newline. Daher funktioniert das mit User-Input nicht.

buckelflips
2017-05-29, 11:39:20
"Normalerweise"? Das heißt es gibt andere Möglichkeiten?
Grundsätzlich erscheint mir das logisch, aber ich habe Schwierigkeiten mich mit sowas abzufinden.
Gerade weil der Compiler doch "nur" in CIL übersetzt. Müsste man doch da drumherum kommen?

Die Konsole kennt die Escape Sequenzen von C# natürlich nicht. Dort müsstest du wahrscheinlich direkt den ASCII/UTF-8 Code eingeben (17 für \n, iirc), damit es in deiner Anwendung auch so ankommt.
Das scheint solange zu funktionieren wie ich keine neue Zeile will. Mit 13 ist das sogar ein Carriage Return und bricht an der Stelle ab. Bei manchen der ersten Unicodes nimmt er die Formatierungen dann als ganz normales Formatzeichen.

Monger
2017-05-29, 12:45:26
Das scheint solange zu funktionieren wie ich keine neue Zeile will. Mit 13 ist das sogar ein Carriage Return und bricht an der Stelle ab. Bei manchen der ersten Unicodes nimmt er die Formatierungen dann als ganz normales Formatzeichen.
Vergiss mal .NET, weil damit hat dein Problem mMn nichts zu tun.

Denke wie eine Konsole. Deine Konsole ist zeilenorientiert, d.h. die normale Interaktion mit der Konsole ist, Zeile für Zeile zu schreiben. Wenn die Konsole mit irgendwas anderem interagieren würde als mit einem .NET Prozess, würdest du vor dem selben Problem sitzen.

Ergo hast du in meinen Augen folgende Möglichkeiten:
a) du wählst eine andere Brücke um zwischen Daten und deinem Prozess zu interagieren als über die Konsole (Named Pipes, REST Anfragen, whatever...)
b) die codierst Zeilenumbrüche explizit um sie in deiner Anwendung wieder zu decodieren
c) du nimmst deinen Input, trennst ihn anhand der Zeilenumbrüche auf, und schiebst ihn Zeile für Zeile via Readline in deinen Prozess rein. Dort kannst du dann ihn wieder zusammensetzen oder sonstwas machen.

Wenn du keinen Technologiewechsel machen willst, rate ich dir zu c). Das ist auch für einen Benutzer am nachvollziehbarsten, und funktioniert gut mit anderen Konsolenbefehlen zusammen die meistens auch Zeile für Zeile konsumieren und wieder ausspucken.