Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Konsolenanwendung Zeichensatz (https://www.delphipraxis.net/69374-konsolenanwendung-zeichensatz.html)

Martin K 14. Mai 2006 14:43


Konsolenanwendung Zeichensatz
 
Hi,

hab mir mal mit Delphi eine Konsolenanwendung {$APPTYPE CONSOLE} gemacht.
Leider gibt es hier Probleme bei der Formatierung von Strings über WriteLn().

Anscheinend wird hier nicht der "normale" ASCII-Zeichensatz verwendet, sondern ein anderer.
z.B. hat ein ä im normalen Zeichensatz den Index #228, bei der Konsole erhalt ich ein ä über #132.

Gibt es evtl. eine einfache Umwadlung des Zeichensatzes?

Frickeldrecktuxer_TM 14. Mai 2006 15:06

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Martin K
Anscheinend wird hier nicht der "normale" ASCII-Zeichensatz verwendet, sondern ein anderer.

Stimmt, du verwendest den ANSI-Verschnitt und möchtest deine Strings vor der Ausgabe in einen weiteren proprietären Zeichensatz umwandeln, der deiner Codepage entspricht: MSDN-Library durchsuchenOemToChar und MSDN-Library durchsuchenCharToOem

Zitat:

Zitat von Martin K
z.B. hat ein ä im normalen Zeichensatz den Index #228, bei der Konsole erhalt ich ein ä über #132.

ASCII kennt keine Umlaute.

Martin K 14. Mai 2006 15:16

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Frickeldrecktuxer_TM
Zitat:

Zitat von Martin K
Anscheinend wird hier nicht der "normale" ASCII-Zeichensatz verwendet, sondern ein anderer.

Stimmt, du verwendest den ANSI-Verschnitt und möchtest deine Strings vor der Ausgabe in einen weiteren proprietären Zeichensatz umwandeln, der deiner Codepage entspricht: MSDN-Library durchsuchenOemToChar und MSDN-Library durchsuchenCharToOem

Hm, wenn ich diese beiden Funktionen verwende, wird meine Konsole gleich nach dem Ausfüren wieder beendet.
Kann man denn nicht allgemein, irgendwo am Anfang bei der Deklaration den Zeichensatz eines Strings festlegen?

Zitat:

Zitat von Frickeldrecktuxer_TM
Zitat:

Zitat von Martin K
z.B. hat ein ä im normalen Zeichensatz den Index #228, bei der Konsole erhalt ich ein ä über #132.

ASCII kennt keine Umlaute.

Hä? Seit wann denn das ???
Der ASCII-Zeichensatz besteht doch aus 256 Zeichen und da sind auch Umlaute mit dabei...
Oder liege ich jetzt vollkommen daneben?
:gruebel:

Olli 14. Mai 2006 15:22

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Martin K
Hä? Seit wann denn das ???
Der ASCII-Zeichensatz besteht doch aus 256 Zeichen und da sind auch Umlaute mit dabei...
Oder liege ich jetzt vollkommen daneben?
:gruebel:

1.) ASCII kennt nur 128 Zeichen. Der 256 Zeichen-Satz ist EASCII!
2.) Im orginal (E)ASCII sind tatsächlich keine Umlaute enthalten. Es gibt aber Codeseiten, mit denen man Umlaute reinmappen kann.

Apropos: wenn die Konsole sofort wieder geschlossen wird, riecht das eher nach einer Exception. Mglw. rufst du obige Funktionen nicht korrekt auf?

Martin K 14. Mai 2006 15:29

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Olli
1.) ASCII kennt nur 128 Zeichen. Der 256 Zeichen-Satz ist EASCII!

Das wusste ich noch gar nicht...

Zitat:

Zitat von Olli
Apropos: wenn die Konsole sofort wieder geschlossen wird, riecht das eher nach einer Exception. Mglw. rufst du obige Funktionen nicht korrekt auf?

Ich rufe sie so auf:
Delphi-Quellcode:
var s1,s2: string;

{...}
  s1 := 'ä';
  CharToOEM( PChar(s1), PChar(s2));
  WriteLn(s2);
Ist da was falsch?
Habe diese Funktionen noch nie benutzt...

Frickeldrecktuxer_TM 14. Mai 2006 15:31

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Martin K
Hm, wenn ich diese beiden Funktionen verwende, wird meine Konsole gleich nach dem Ausfüren wieder beendet.

Gibt es keine Fehlermeldung oder ähnliches? Wie wendest du denn die Funktionen an?

Zitat:

Zitat von Martin K
Kann man denn nicht allgemein, irgendwo am Anfang bei der Deklaration den Zeichensatz eines Strings festlegen?

Bei String-Konstanten würde es sich anbieten, den String im passenden Zeichensatz in den Quellcode zu legen, sofern der DCC das mitmacht. Ansonsten weiß ich nicht, ob es eine ANSI-kompatible Codepage für DOS (und somit auch cmd.exe) gibt.

Zitat:

Zitat von Martin K
Zitat:

Zitat von Frickeldrecktuxer_TM
ASCII kennt keine Umlaute.

Hä? Seit wann denn das ???

Seit Anbeginn der Zeit, ähh, seit es ASCII gibt ;-)

Zitat:

Zitat von Martin K
Der ASCII-Zeichensatz besteht doch aus 256 Zeichen und da sind auch Umlaute mit dabei...
Oder liege ich jetzt vollkommen daneben?

ASCII sind 128 Zeichen. Welche das sind, kannst du in jeder zweitklassigen ASCII-Tabelle nachschlagen, die bei 0x7F aufhört, oder in einer Unicode-Referenz, falls du eine hast, denn die ASCII-Zeichen sind identisch mit den 128 ersten Unicode-Zeichen. Unter DOS hat man für 8bittige Zeichen Codepages eingeführt, nach Bedarf an diakritischen Zeichen (Akzente, Umlaute und was sonst noch kreucht und fleucht). Unter Windows dann eben ANSI (mittlerweile geht der Trend aber wohl auch unter Windows in Richtung Unicode, zumindest beim Dateisystem). Mit ASCII in Reinform kommst du normalerweise seit 20 Jahren nicht mehr in Berührung.

Frickeldrecktuxer_TM 14. Mai 2006 15:33

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Martin K
Ist da was falsch?

Ja. Beide Funktionen verlangen, daß der Zielpuffer groß genug ist. Dein s2 hat aber die Länge 0 (Null, nicht O), weil du die Variable zuvor noch nicht gebraucht hast. Ein passendes SetLength() auf den String sollte für Abhilfe sorgen, denn das allokiert hinreichend viel Speicher im String.

Martin K 14. Mai 2006 15:34

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Frickeldrecktuxer_TM
Zitat:

Zitat von Martin K
Kann man denn nicht allgemein, irgendwo am Anfang bei der Deklaration den Zeichensatz eines Strings festlegen?

Bei String-Konstanten würde es sich anbieten, den String im passenden Zeichensatz in den Quellcode zu legen, sofern der DCC das mitmacht. Ansonsten weiß ich nicht, ob es eine ANSI-kompatible Codepage für DOS (und somit auch cmd.exe) gibt.

Und wie geht das? :gruebel:

//Edit:
dieses elende quote-Zeug's... Ich hasse es!

Martin K 14. Mai 2006 15:42

Re: Konsolenanwendung Zeichensatz
 
Okay, so geht's:
Delphi-Quellcode:
{...}
  s1 := 'ä';
  SetLength(s2, Length(s1));
  CharToOEM( PChar(s1), PChar(s2));
  WriteLn(s2);
Aber ich würde es gerne mit der anderen Methode machen, dass die Strings im Quellcode direkt im DOS-Zeichensatz formatiert sind.
Also wenn ich eingebe:
Delphi-Quellcode:
  WriteLn('ä');
...dann soll das auch so in der Ausgabe meiner Konsole richtig stehen...

Olli 14. Mai 2006 15:42

Re: Konsolenanwendung Zeichensatz
 
SetLength benutzen.

Sorry, war kein roter Kasten da.

Olli 14. Mai 2006 15:45

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Martin K
Aber ich würde es gerne mit der anderen Methode machen, dass die Strings im Quellcode direkt im DOS-Zeichensatz formatiert sind.

Kein Problem. Öffne ein DOS-Fenster, gib ein 'EDIT' und öffne aus dem DOS-Editor heraus deine Datei. Nun kannst du deinen Delphi-Source mit dem DOS-Editor bearbeiten.

Etwas unpraktikabel vielleicht, aber allemal eine Variante.

Martin K 14. Mai 2006 15:49

Re: Konsolenanwendung Zeichensatz
 
Hm, ja das ist eine Möglichkeit, finde ich aber nicht sehr gut.

Ich hätte es gerne so:
Zitat:

Zitat von Martin K
Kann man denn nicht allgemein, irgendwo am Anfang bei der Deklaration den Zeichensatz eines Strings festlegen?

Weil ich auch noch andere Units eingebunden habe, die auch Strings mit Umlauten in Funktionen/Prozeduren zurückliefern.

Olli 14. Mai 2006 15:54

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Martin K
Kann man denn nicht allgemein, irgendwo am Anfang bei der Deklaration den Zeichensatz eines Strings festlegen?

Nein. Und die benutzte Codeseite entspricht den Einstellungen deines Systems (oder deines Benutzers, je nachdem).

Martin K 14. Mai 2006 16:01

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Olli
Zitat:

Zitat von Martin K
Kann man denn nicht allgemein, irgendwo am Anfang bei der Deklaration den Zeichensatz eines Strings festlegen?

Nein. Und die benutzte Codeseite entspricht den Einstellungen deines Systems (oder deines Benutzers, je nachdem).

Kann man die ändern?
(Also in Delphi, für ein Programm)

Frickeldrecktuxer_TM 14. Mai 2006 16:11

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Martin K
Kann man die ändern?
(Also in Delphi, für ein Programm)

Laut http://www.uwe-sieber.de/codepage_e.html mit CHCP. Eine passende Codepage sollte laut Google 1252 sein, sofern die in cmd.exe verfügbar ist. Falls nicht, weiß ich auch nicht, welche CP du da am besten nimmst.
Aber ist es denn wirklich so schlimm alle Vorkommen von WriteLN() durch CustomWriteLN() zu ersetzen und dann einfach folgende Funktion zu schreiben?
Delphi-Quellcode:
procedure CustomWriteLN(S: String);
var
  buf: String;
begin
  SetLength(buf, Length(S));
  CharToOEM(PChar(S), PChar(buf));
  WriteLN(buf);
end;

Martin K 14. Mai 2006 16:12

Re: Konsolenanwendung Zeichensatz
 
So, hab mir jetzt so was gebastelt:
Delphi-Quellcode:
procedure Write(const src: string);
var dst: string;
begin
  if src='' then
    WriteLn('')
  else
  begin
    SetLength(dst,Length(src));
    CharToOEM(PChar(src),PChar(dst));
    WriteLn(dst);
  end;
end;
Warum funzt das eigentlich net bei leeren Strings ?

Bei leeren Strings ist mein Programm immer abgestürzt, deshalb die IF-Abfrage.

DGL-luke 14. Mai 2006 19:03

Re: Konsolenanwendung Zeichensatz
 
ach ja... das Problem mit dem sofortigen schließen... Könnte es sein, dass nach dem Writeln einfach gleich das finale "end." kommt? Das macht nämlich genau das, was man von ihm erwartet. :zwinker:

Die Lösung verrat ich natürlich auch gleich: Ein einfaches "ReadLn" kehrt erst zurück, wenn du die Enter-Taste betätigst.

xaromz 14. Mai 2006 21:14

Re: Konsolenanwendung Zeichensatz
 
Hallo,
Zitat:

Zitat von Martin K
Warum funzt das eigentlich net bei leeren Strings ?

Bei leeren Strings ist mein Programm immer abgestürzt, deshalb die IF-Abfrage.

Weil der String "dst" mindestens ein Zeichen lang sein muss, sonst mag CharToOEM nicht. Steht leider auch nicht im PSDK.

Gruß
xaromz

implementation 19. Mär 2009 17:25

Re: Konsolenanwendung Zeichensatz
 
ich möchte in meinem Programm möglichst die Zeichen ╣║╗╝╚╔╩╦╠═╬ benutzen.
Da hilft aber auch CharToOem() nicht weiter.
Aber es scheint irgendwie möglich zu sein.
Weiß jemand wie?

mjustin 19. Mär 2009 19:16

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von Frickeldrecktuxer_TM
die ASCII-Zeichen sind identisch mit den 128 ersten Unicode-Zeichen

Nicht direkt. Bei UTF-16 und UCS-2 ist jedes Unicodezeichen in (mindestens) zwei Bytes kodiert, bei UCS-4 und UTF-32 sogar in 4 - auch die Zeichen, die den ASCII Zeichen entsprechen, belegen also mehrere Bytes. Bei UTF-8 stimmt gibt es die Übereinstimmung mit ASCII bei der Kodierung der ersten 128 Zeichen. Weitere Unicode Zeichen benötigen in UTF-8 bis zu vier Bytes ...

p80286 20. Mär 2009 13:19

Re: Konsolenanwendung Zeichensatz
 
Zitat:

Zitat von implementation
ich möchte in meinem Programm möglichst die Zeichen ╣║╗╝╚╔╩╦╠═╬ benutzen.
Da hilft aber auch CharToOem() nicht weiter.
Aber es scheint irgendwie möglich zu sein.
Weiß jemand wie?

Was für eine Art Programm ist es denn? Konsole?
Dann mußt Du "nur" die richtigen Codes ausgeben: write(#$C8) für ╚

Wenn Du z.B. ein TMemo nutzen willst, dann solltest Du den Font Terminal verwenden.

Gruß K-H

implementation 22. Mär 2009 18:57

Re: Konsolenanwendung Zeichensatz
 
konsole, ja


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz