Wieso ist 'Ä' -60 ?



  • hi,
    ich hab visual c++ und multibyte zeichensatz in den projekteinstellungen gesetzt.
    nu mach ich

    int AE = 'Ä'
    

    der wert ist

    -60
    

    wie kommt man auch -60 ?
    😕



  • 'Ä' = 196, da aber es irdenwo in ein singed char konvertiert wird => Wird aus 196 die 60.



  • Die ersten 128 sind vom Standard definiert. Der Rest ist dem Betriebssystem ueberlassen.


  • Mod

    ASCIIIIIII schrieb:

    Die ersten 128 sind vom Standard definiert. Der Rest ist dem Betriebssystem ueberlassen.

    Blödsinn oder sehr ungenau ausgedrückt.
    Das ist vom ASCII Standard so definiert, ja. Es braucht sich aber kein Computer/Compiler/Betriebssystem da dran zu halten.
    Und es ist nicht so, dass für den Rest nicht auch Standards existieren würden.



  • SeppJ schrieb:

    ASCIIIIIII schrieb:

    Die ersten 128 sind vom Standard definiert. Der Rest ist dem Betriebssystem ueberlassen.

    Blödsinn oder sehr ungenau ausgedrückt.
    Das ist vom ASCII Standard so definiert, ja. Es braucht sich aber kein Computer/Compiler/Betriebssystem da dran zu halten.
    Und es ist nicht so, dass für den Rest nicht auch Standards existieren würden.

    Das kann man auch hoeflicher ausdruecken. Ich hab dich wohl kaum angegriffen?

    Entschuldigung, dass ich "Stuss" erzaehlt habe. Habe es jedoch nicht anders gelernt:

    Only the first 128 (i.e., ASCII 0 through ASCII 127) are common among all computers, whether they are a PC, a Mac, a UNIX or VMS mainframe, a printer, or some other computer-related equipment. Everyone follows this standard. Note that only 7 bits are required to yield the first 128 combinations. During antiquity, the 8th bit was used as the parity bit. Nowadays, computers make use of this bit to code another 128 characters, mostly the accented characters of the Western European languages. Note that all characters on the upper half of the ASCII table (i.e., ASCII 128 through ASCII 255) uniformly have the highest bit set to "1". The U.S. DOS has its own set of characters for the second half of the ASCII codes; however, this coding is NOT unique among different computers, or even among different DOS settings or software. For example, DOS and Windows have different uses for ASCII 128 through ASCII 255, although these two products both come from the same company! The ISO-8859-1 standard includes the first 128 characters plus the accented ones.



  • Ja, ASCII und seine Erweiterungen sind so ziemlich die bekannteste und meistgenutzte Zeichenkodierung. Aber es gibt auch einige Alternativen, die unabhängig sind, z.B. EBCDIC. Und der C/C++ Standard legt nicht fest, welche Codierung genutzt wird.


  • Mod

    ASCIIIIIII schrieb:

    Das kann man auch hoeflicher ausdruecken. Ich hab dich wohl kaum angegriffen?

    Dann entschuldige ich mich vielmals. Namen machen Leute und dein Nickname erweckte bei mir den Eindruck, dass du nicht wirklich helfen wolltest, sondern bewusst falsche Tatsachen beschreiben hast.



  • SeppJ schrieb:

    ASCIIIIIII schrieb:

    Das kann man auch hoeflicher ausdruecken. Ich hab dich wohl kaum angegriffen?

    Dann entschuldige ich mich vielmals. Namen machen Leute und dein Nickname erweckte bei mir den Eindruck, dass du nicht wirklich helfen wolltest, sondern bewusst falsche Tatsachen beschreiben hast.

    Oh ok.

    Nur koenntest du mir noch den falschen Teil meiner Aussage erlaeutern? 🙂



  • hans312 schrieb:

    Nur koenntest du mir noch den falschen Teil meiner Aussage erlaeutern? 🙂

    "Der Standard" a.k.a. "der C++ Standard" setzt ASCII nicht voraus.



  • cooky451 schrieb:

    hans312 schrieb:

    Nur koenntest du mir noch den falschen Teil meiner Aussage erlaeutern? 🙂

    "Der Standard" a.k.a. "der C++ Standard" setzt ASCII nicht voraus.

    Oh ok. [Siehe CStoll Post] 🤡
    Danke fuer die Erlaeuterung


  • Mod

    hans312 schrieb:

    Nur koenntest du mir noch den falschen Teil meiner Aussage erlaeutern? 🙂

    1. Es gibt keinen Standard, der dir die ersten 128 garantiert. Es gibt verschiedene Standards dafür, an welchen dein Computer sich hält, ist nicht festgelegt (ja, es ist ziemlich sicher, dass fast alle Computer ASCII benutzen, aber du kannst dir nicht 100% sicher sein, wenn du an einem beliebigen Computer in der Welt gesetzt wirst, dass dies so ist)
    2. Für alles oberhalb von 128 gilt das gleiche. Auch hier gibt es Standards, an die sich ein Computer halten kann oder auch nicht und es gibt auch verschiedene und wenn du an einem beliebigen Computer in der Welt gesetzt wirst, kannst du nicht sicher sein, was der Fall ist.
    ➡ Im Prinzip ist gilt für beide Zahlenbereiche das gleiche, nichts ist garantiert. Der Unterschied ist bloß, dass ASCII ein bisschen verbreiteter ist, als z.B. Unicode.

    edit: Da war ich mal wieder zu langsam.
    edit2: Und wenn ich schon am Editieren bin: Auf gewisse Sachen kann man sich schon verlassen. Zum Beispiel ist garantiert, dass ein in C geschriebenes Programm sich auf die Folge der Ziffern 0- 9 verlassen kann. Auf einem Computer bei dem das nicht so ist, kann kein (standardkonformer) C-Compiler laufen. Außerdem könnten bestimmte Betriebssysteme dir Garantien machen, bei DOS ist (bin mir nicht 100% sicher, aber ziemlich) zum Beispiel sicher, dass es ASCII benutzt.



  • Ist

    char c = 'Ä';
    

    überhaupt ein wohlgeformtes C++-Programm?

    Ich weiß es gerade nicht. Ich kann mir gut aber vorstellen, dass es nicht unter die strenge Definition von "wohlgeformt" fällt, weil der Compiler die Bytes, die sich hinter dem Ä verstecken ja im allgemeinen nicht verstehen kann, weil der C++-Standard kein Encoding vorschreibt. Insbesondere weiß der Editor ja auch nicht, ob er das Ä nun für den C++-Compiler utf8-kodieren soll oder latin1 oder was auch immer.



  • Christoph schrieb:

    Ist

    char c = 'Ä';
    

    überhaupt ein wohlgeformtes C++-Programm?

    Interessante Frage! Der C++ Standard spricht hier von einem "source character set", welcher nur 96 Zeichen umfasst (a-z, A-Z, 0-9 und _{}[]#()<>%:;.?*+-/^&|~!=,\"'). Und wenn ich micht nicht verguckt habe, sind nur Zeichen aus diesem "source character set" in Char-Literals erlaubt.



  • krümelkacker schrieb:

    Christoph schrieb:

    Ist

    char c = 'Ä';
    

    überhaupt ein wohlgeformtes C++-Programm?

    Interessante Frage! Der C++ Standard spricht hier von einem "source character set", welcher nur 96 Zeichen umfasst (a-z, A-Z, 0-9 und _{}[]#()<>%:;.?*+-/^&|~!=,\"'). Und wenn ich micht nicht verguckt habe, sind nur Zeichen aus diesem "source character set" in Char-Literals erlaubt.

    Verzeihung, aber hier gefällt mir was nicht.

    Denn ich habe damals, um mir das Prinzip der Zeichensätze, Codepages und Lokalen beizubringen, versucht, das System, wie die DOS-Konsole auf Windows meine hübschen Sätze mit Umlauten ruiniert, durchzublicken. In den Quellcode selbst darf man keine Zeichen einfügen, die nicht zwischen 32 und 127 liegen (es sei denn \r und \n - zumindest ist das bei VS so), aber man kann als Stringliteral sehr wohl Sonderzeichen 'Ä' oder 'ß' angeben.

    Es scheint wohl so, dass der Wert, den das Zeichen in der gegenwärtigen Codepage (oder in Unicode) belegt, direkt reingeschrieben wird. Bei Codepage 1252 und einem 'Ä' würde in c dann 196 als Wert stehen. Wenn man nun verwegen oder ein Anfänger ist und das ganze unter der Eingabeaufforderung ausgibt, kommt nur das Zeichen '─' raus - weil dieses Zeichen in der Codepage 850 nun einmal den Wert 196 besitzt. Das Zeichen für 'Ä' wäre hier aber 142 ...

    Ich vermute also stark, dass der Wert des Zeichens einfach den Wert in der gegenwärtig ausgewählten Codepage annimmt.



  • Der aus dem Westen ... schrieb:

    In den Quellcode selbst darf man keine Zeichen einfügen, die nicht zwischen 32 und 127 liegen (es sei denn \r und \n - zumindest ist das bei VS so), aber man kann als Stringliteral sehr wohl Sonderzeichen 'Ä' oder 'ß' angeben.

    Es ging mir bei meiner Frage nicht darum, wie es ein bestimmter Compiler macht, oder wie es zu funktionieren scheint, sondern ob es ein wohlgeformtes C++-Programm im Sinne des C++-Standards ist.

    krümelkackers Antwort nach ist es wohl tatsächlich kein wohlgeformtes C++-Programm.



  • Der aus dem Westen ... schrieb:

    Verzeihung, aber hier gefällt mir was nicht. [...]

    Du hast zwar nirgends Bezug auf den ISO/IEC 14882:2003 Standard genommen, mich aber doch dazu bekommen, dort nochmal nach zu gucken.

    Es ist die Rede von 3 Zeichensätzen:

    • basic source character set (Leerzeichen, horizontal-tab, vertical-tab, form-feed, new-line und 91 graphische Zeichen a-z, A-Z, 0-9 und _{}[]#()<>%:;.?*+-/^&|~!=,\"')
    • physical source file character set (enthält das basic source character set)
    • execution character set (enthält das basic source character set)

    Ich hatte die ersten beiden in einen Topf geschmissen. Das war falsch.

    In der ersten Phase der Übersetzung werden alle Zeichen aus der Quellcodedatei zu Zeichen aus dem Basic Source Character konvertiert. Trigraphs werden dabei auch ersetzt. Jedes Zeichen aus dem source character set, welches nicht um basic source character set ist, wird hier durch ein "universal-character-name" (\uNNNN oder \UNNNNNNNN wobei N der Unicode-Codepoint ist) ersetzt, der diesem Zeichem entspricht. Beispiel:

    Ä --> \u00C4
    

    Diesen universellen Namen muss der Compiler aber eigentlich richtig in das execution character set (ECS) übersetzen. Wenn das ECS jetzt die Codepage 850 sein sollte, dann müsste das Byte 0x8E im Executable zu finden sein.

    Zitate aus dem Standard:

    §2.1/1.1:

    Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set (introducing new-line characters for end-of-line indicators) if necessary. Trigraph sequences (2.3) are replaced by corresponding single-character internal representations. Any source file character not in the basic source character set (2.2) is replaced by the universal-character-name that designates that character. (An implementation may use any internal encoding, so long as an actual extended character encountered in the source file, and the same extended character expressed in the source file as a universal-character-name (i.e. using the \uXXXX notation), are handled equivalently.)

    §2.2

    universal-character-name:
      \u hex-quad
      \U hex-quad hex-quad
    

    §2.2/2

    The character designated by the universal-character-name \UNNNNNNNN is that character whose character short name in ISO/IEC 10646 is NNNNNNNN; the character designated by the universal-character-name \uNNNN is that character whose character short name in ISO/IEC 10646 is 0000NNNN. If the hexadecimal value for a universal character name is less than 0x20 or in the range 0x7F-0x9F (inclusive), or if the universal character name designates a character in the basic source character set, then the program is illformed.

    §2.13.2

    character-literal:
      ’c-char-sequence’
      L’c-char-sequence’
    
    c-char-sequence:
      c-char
      c-char-sequence c-char
    
    c-char:
      any member of the source character set except
        the single-quote ’, backslash \, or new-line character
      escape-sequence
      universal-character-name
    

    §2.13.2/5

    A universal-character-name is translated to the encoding, in the execution character set, of the character named. If there is no such encoding, the universal-character-name is translated to an implementationdefined encoding. [Note: in translation phase 1, a universal-character-name is introduced whenever an actual extended character is encountered in the source text. Therefore, all extended characters are described in terms of universal-character-names. However, the actual compiler implementation may use its own native character set, so long as the same results are obtained. ]



  • Christoph schrieb:

    Ist

    char c = 'Ä';
    

    überhaupt ein wohlgeformtes C++-Programm?

    So wie ich das lese: nein.

    char c = '\u00c4';
    

    wäre in Ordnung, und einer Implementation steht es frei, Ersteres in Letzteres zu übersetzen.



  • camper schrieb:

    Christoph schrieb:

    Ist

    char c = 'Ä';
    

    überhaupt ein wohlgeformtes C++-Programm?

    So wie ich das lese: nein.

    char c = '\u00c4';
    

    wäre in Ordnung, und einer Implementation steht es frei, Ersteres in Letzteres zu übersetzen.

    Ich verstehe das etwas anders. Wenn ein Ä Teil des source character sets ist, dann hat diese "Übersetzung" stattzufinden. Der Wert von '\u00C4' ist aber meinem Verständnis nach durch das execution character set festgelegt. Also, angenommen das ECS ist "Codepage 850" und char is vorzeichenlos, dann verstehe ich das so, dass folgendes gelten müsste:

    '\u00C4' == 0x8E
    


  • krümelkacker schrieb:

    Es ist die Rede von 3 Zeichensätzen:

    • basic source character set (Leerzeichen, horizontal-tab, vertical-tab, form-feed, new-line und 91 graphische Zeichen a-z, A-Z, 0-9 und _{}[]#()<>%:;.?*+-/^&|~!=,\"')
    • source character set (enthält das basic source character set)
    • execution character set (enthält das basic source character set)

    Ich sehe im Standard nirgendwo ein source character set das nicht das basic source character set ist.

    'Ä' ist kein Teil davon.



  • camper schrieb:

    krümelkacker schrieb:

    Es ist die Rede von 3 Zeichensätzen:

    • basic source character set (Leerzeichen, horizontal-tab, vertical-tab, form-feed, new-line und 91 graphische Zeichen a-z, A-Z, 0-9 und _{}[]#()<>%:;.?*+-/^&|~!=,\"')
    • physical source file character set (enthält das basic source character set)
    • execution character set (enthält das basic source character set)

    Ich sehe im Standard nirgendwo ein source character set das nicht das basic source character set ist.

    'Ä' ist kein Teil davon.

    §2.1/1

    Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set (introducing new-line characters for end-of-line indicators) if necessary. Trigraph sequences (2.3) are replaced by corresponding single-character internal representations. Any source file character not in the basic source character set (2.2) is replaced by the universal-character-name that designates that character. (An implementation may use any internal encoding, so long as an actual extended character encountered in the source file, and the same extended character expressed in the source file as a universal-character-name (i.e. using the \uXXXX notation), are handled equivalently.)

    Nach dieser Phase gibt es keine Zeichen mehr, die nicht im "basic character set" sind; denn ein universal-character-name besteht aus Zeichen, die aus dem basic source character set kommen (Beispiel: \u00C4, also Backslash, u und HexQuad). Von daher braucht der Rest des Standards da auch nicht mehr drauf eingehen. Der Zeichensatz der Eingabedatei könnte ein Ä enthalten; denn, was das für ein erweiterter Zeichensatz ist, wurde nicht näher beschrieben und die letzte unterstrichene Stelle im zitierten Text macht klar, dass auch Zeichen vorkommen können, die nicht im basic source character set enthalten sind. Die werden dann eben nur durch ein universal-character-name ersetzt.

    Die Definition von "well-formed" habe ich jetzt nicht im Kopf. Aber, wenn man weiß, dass die C++ Implementierung, die man nutzt, Quellcodedateien zB mit ISO-8859-1-, UTF-8-- oder UTF-16-Kodierung lesen und verstehen kann, dann darf natürlich auch ein 'Ä' im Quellcode auftauchen. Das, was am Ende rauskommt, ist äquivalent zu dem, was man bekommen würde, hätte man stattdessen '\u00C4' geschrieben.

    Dem GCC kann man über eine Option sagen, was für eine Zeichenkodierung benutzt worden ist:

    [...]
    The character sets of the input files are specified using the -finput-charset= option.

    All preprocessing work (the subject of the rest of this manual) is carried out in the source character set. If you request textual output from the preprocessor with the -E option, it will be in UTF-8.
    [...]

    Edit:
    Ich sehe gerade, dass sogar universelle Zeichennamen in Bezeichnern erlaubt sind. Theoretisch wäre dann auch so etwas möglich:

    void föö();
    

    Aber der GCC unterstützt das zB nicht.

    Edit2:
    LOL. In C++2011 werden universal character names nicht mehr in Bezeichnern unterstützt. Interessant.


Anmelden zum Antworten