Wenn Sie eine Zeichenfolge in C haben, können Sie darin direkten Hex-Code hinzufügen.
char str[] = "abcde"; // 'a', 'b', 'c', 'd', 'e', 0x00
char str2[] = "abc\x12\x34"; // 'a', 'b', 'c', 0x12, 0x34, 0x00
Beide Beispiele haben 6 Bytes im Speicher. Nun besteht das Problem, wenn Sie Mehrwert schaffen wollen [a-fA-F0-9]
nach Hex-Eingabe.
//I want: 'a', 'b', 'c', 0x12, 'e', 0x00
//Error, hex is too big because last e is treated as part of hex thus becoming 0x12e
char problem[] = "abc\x12e";
Mögliche Lösung ist das Ersetzen nach der Definition.
//This will work, bad idea
char solution[6] = "abcde";
solution[3] = 0x12;
Das kann funktionieren, aber es wird fehlschlagen, wenn Sie es so formulieren const
.
//This will not work
const char solution[6] = "abcde";
solution[3] = 0x12; //Compilation error!
Wie man richtig einfügt e
nach \x12
ohne Fehler auszulösen?
Warum frage ich? Wenn Sie bauen möchten UTF-8 string als Konstante, müssen Sie hexadezimale Zeichenwerte verwenden, wenn sie größer sind als die ASCII-Tabelle aufnehmen kann.
Verwenden Sie 3 Oktalziffern:
char problem[] = "abc\022e";
oder teilen Sie Ihre Zeichenfolge:
char problem[] = "abc\x12" "e";
Warum diese funktionieren:
-
Im Gegensatz zu Hex-Escapes definiert Standard 3 Ziffern als maximale Anzahl für Oktal-Escapes.
6.4.4.4 Zeichenkonstanten
…
octal-escape-sequence:
\ octal-digit
\ octal-digit octal-digit
\ octal-digit octal-digit octal-digit
…
hexadecimal-escape-sequence:
\x hexadecimal-digit
hexadecimal-escape-sequence hexadecimal-digit
-
Die String-Literal-Verkettung ist als eine spätere Übersetzungsphase definiert als die Literal-Escape-Zeichenkonvertierung.
5.1.1.2 Übersetzungsphasen
…
-
Jedes Element des Quellzeichensatzes und jede Escape-Sequenz in Zeichenkonstanten und Zeichenfolgenliteralen wird in das entsprechende Element des Ausführungszeichensatzes konvertiert. Wenn kein entsprechendes Mitglied vorhanden ist, wird es in ein von der Implementierung definiertes Mitglied konvertiert, bei dem es sich nicht um das Nullzeichen (Breitzeichen) handelt. 8)
-
Benachbarte String-Literal-Tokens werden verkettet.
Da Zeichenfolgenliterale schon früh im Kompilierungsprozess verkettet werden, aber nach die Umwandlung von Escape-Zeichen können Sie einfach verwenden:
char problem[] = "abc\x12" "e";
obwohl Sie möglicherweise eine vollständige Trennung für die Lesbarkeit bevorzugen:
char problem[] = "abc" "\x12" "e";
Für die Sprachanwälte unter uns ist dies abgedeckt C11 5.1.1.2 Translation phases
(meine Betonung):
-
Jedes Quellzeichensatzmitglied und Fluchtabfolge in Zeichenkonstanten und Zeichenfolgenliterale wird in das entsprechende Mitglied des Ausführungszeichensatzes konvertiert; Wenn kein entsprechendes Mitglied vorhanden ist, wird es in ein von der Implementierung definiertes Mitglied konvertiert, bei dem es sich nicht um das Nullzeichen (Breitzeichen) handelt.
-
Benachbarte String-Literal-Tokens werden verkettet.
Warum frage ich? Wenn Sie eine UTF-8-Zeichenfolge als Konstante erstellen möchten, müssen Sie Hexadezimalwerte von Zeichen verwenden, die größer sind, als die ASCII-Tabelle aufnehmen kann.
Nun, nein. Du nicht müssen, zu … haben. Ab C11 können Sie Ihrer String-Konstante ein Präfix voranstellen u8
die dem Compiler mitteilt, dass das Zeichenliteral in UTF-8 vorliegt.
char solution[] = u8"no need to use hex-codes á駵";
(Gleiches wird übrigens auch von C++11 unterstützt)
Duplizieren: stackoverflow.com/questions/35180528/…. Ich werde diesen schließen, da ich denke, dass die hier geposteten Antworten vollständiger sind, wobei der Standard eher in der Antwort als in Kommentaren zitiert wird.
– Ludin
10. August 2017 um 12:41 Uhr