Forum: PC-Programmierung Char als Klartext im Quellcode ©


von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

Irgendwo hatte ich gelesen, das man beim arbeiten mi Char möglichst auch 
gleich mit dem Char arbeiten soll und nicht mit der Zugehörigen Nummer, 
also © und nicht #132 oder sowas..alleine schon, da man dann beim 
Portieren plötzlich  anderen Zeichen hat.
Nur wenn ich schreibe
printf("%c",©);
gibt es eine Fehlermeldung..

von Bimbo. (Gast)


Lesenswert?

C-Buch lesen: printf("%c",'©');

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

hat sich erledigt..nun geht es plötzlich mit ©

aber das Zeichen ▒ funktioniert nicht, also Zeichen #177

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Thomas M. schrieb:
> aber das Zeichen ▒ funktioniert nicht,

Was auch immer "funktioniert nicht" heißen mag…

> also Zeichen #177

In welchem Zeichensatz?

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

egal in welchem..es kommt ja eine Fehlermeldung.
Ganz normal mit codeblocks unter Win10

Den Zeichensatz den Windows halt hat..tipp doch einfach alt gr 177...den 
Zeichensatz halt...

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> egal in welchem..es kommt ja eine Fehlermeldung.

Ah. Eine Fehlermeldung. Dann ist ja klar, was Sache ist.

von test (Gast)


Lesenswert?

Thomas M. schrieb:
> Den Zeichensatz den Windows halt hat..tipp doch einfach alt gr 177...den
> Zeichensatz halt...

"Den Zeichensatz der halt zufällig irgendwie da ist" zu nutzen ist ne 
blöde Idee.

Üblicherweise nimmt man Unicode. Hat das Zielsystem nicht genug 
Ressourcen zur Nutzung von Unicode muss man sich halt überlegen was Sinn 
macht. So könnte es z.B. Sinn machen den selben Zeichensatz zu nutzen 
wie das verwendete Textdisplay.

von Nano (Gast)


Lesenswert?

@ ts
Lies mal die wikipedia Artikel zu Ascii und Unicode.
Quellcode immer als UTF-8 speichern, notfalls nen anderen Editor 
verwenden.
Windows arbeitet intern mit utf-16. Vorteil = immer gleiche breite beim 
durchlaufen, z.b eines Arrays.

von Sven P. (Gast)


Lesenswert?

Nano schrieb:
> Vorteil = immer gleiche breite beim
> durchlaufen, z.b eines Arrays.

Typischer Anfängerfehler...

von Jemand (Gast)


Lesenswert?

Nano schrieb:
> utf-16. Vorteil = immer gleiche breite beim durchlaufen, z.b eines
> Arrays.

Nö, UTF-16 kodiert ebenfalls mit dynamischer Länge. UTF-32 nicht, aber 
da kann man immer noch nicht annehmen, dass jedes "Zeichen" (Codepoint) 
genau einem Schiftzeichen (Grapheme) entspricht.

von Rolf M. (rmagnus)


Lesenswert?

Thomas M. schrieb:
> egal in welchem..es kommt ja eine Fehlermeldung.

Ach so? Prima Salami-Taktik:

Schritt 1: "funktioniert nicht"
Schritt 2: "es kommt ja eine Fehlermeldung"

Vielleicht kriegen wir noch einen dritten Schritt hin, in dem du auch 
noch verrätst, welche Fehlermeldung das ist.

Thomas M. schrieb:
> egal in welchem..es kommt ja eine Fehlermeldung.
> Ganz normal mit codeblocks unter Win10
>
> Den Zeichensatz den Windows halt hat..tipp doch einfach alt gr 177...den
> Zeichensatz halt...

Das gibt bei mir ¹{{ aus, aber das mag daran liegen, dass ich hier kein 
Windows hab.

C definiert, dass es zwei Zeichensätze gibt, die da eine Rolle spielen.
Das "Source Character Set" ist der Zeichensatz, den er im Quellcode 
annimmt, und das "Execution Character Set" ist das, welches dann später 
im Programm landet. Der Compiler konvertiert das beim 
Übersetzungsvorgang.
Damit das ganze funktioniert, muss dein Editor den selben Zeichensatz 
verwenden, wie das Source Character Set des Compilers, und das 
Ausgabemedium, auf den nachher dein Programm seinen Text schreibt, muss 
mit  dem Execution Characer Set arbeiten.
Du hast den verwendeten Compiler verschwiegen, aber bei gcc gibt's dafür 
z.B. die Compiler-Optionen -finput-charset und -fexec-charset.


Nano schrieb:
> @ ts
> Lies mal die wikipedia Artikel zu Ascii und Unicode.

Und zu Universal Coded Character Set.

> Quellcode immer als UTF-8 speichern, notfalls nen anderen Editor
> verwenden.
> Windows arbeitet intern mit utf-16. Vorteil = immer gleiche breite beim
> durchlaufen, z.b eines Arrays.

Für den kompletten Unicode-Zeichensatz reichen 16 Bits nicht aus. UTF-16 
hat wie UTF-8 eine variable Größe.

von test (Gast)


Lesenswert?

Oder man hat modifiers, oder man muss zur Ausgabe in andere Charsets 
wandeln.

Unicode macht ohne Betriebssystem (welches die gesamten Funktionen zum 
Umgang mit Unicode zur Verfügung stellt) keinen Spaß.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rolf M. schrieb:
>> tipp doch einfach alt gr 177...den
>> Zeichensatz halt...
>
> Das gibt bei mir ¹{{ aus, aber das mag daran liegen, dass ich hier kein
> Windows hab.

Und daran, daß Du die Ziffern nicht auf dem Zehnerblock eintippst.

von Philipp Klaus K. (pkk)


Lesenswert?

Ich empfehle die Lektüre von Abschnitt 5.2.1 ("Character sets"), 6.4.4.4 
("Character constants"), 6.4.5 ("String literals") und 7.21.6 
("Formatted input/output function") des ISO C17 standards (N2310 - was 
zwar formal ein erster Entwurf zu C2X ist, sich aber praktisch nahezu 
nur in zwei Ziffern in den Seitenköpfen vom eigentlichen C17-Standard 
unterscheidet).

Philipp

von Rolf M. (rmagnus)


Lesenswert?

Rufus Τ. F. schrieb:
> Und daran, daß Du die Ziffern nicht auf dem Zehnerblock eintippst.

Stimmt. Wenn ich den benutze, passiert einfach das selbe, was auch ohne 
AltGr passiert wäre.

von Es ist zum verzweifeln (Gast)


Lesenswert?

>Für den kompletten Unicode-Zeichensatz reichen 16 Bits nicht aus.

Ganz übles Thema. Hat Jahrzehnte gedauert, bis 16bit Unicode überall 
problemlos funktioniert. Wir könnten jetzt glücklich und zufrieden 
Unicode benutzen. Und was passiert - diese Knalltüten legen die Smilies 
in eine andere 16bit Codepage.

Jetzt haben wir wieder diesen Wirrwarr mit den Präfixen und 
unterschiedlichen Kodierungen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es ist zum verzweifeln schrieb:
> Jetzt haben wir wieder diesen Wirrwarr mit den Präfixen und
> unterschiedlichen Kodierungen.

Oder man verzichtet auf die Dinger. Der Informationsgehalt geht eh' 
gegen Null.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> Den Zeichensatz den Windows halt hat

Da fängt das Problem schon an: Windows verwendet leider nicht eine
Zeichenkodierung, sondern gleich mehrere und diese sogar parallel, was
immer wieder zur Verwirrung führt.

Bei moderneren Betriebssystemen kann man die Zeichenkodierung zwar
ebenfalls in vielfältiger Weise konfigurieren, man legt sich aber für
eine konkrete Installation meist auf eine einzige fest (bspw. UTF-8),
wodurch solch ein Durcheinander wie in Windows gar nicht erst entsteht.

Auf einem Windows-PC in Westeuropa sind typischerweise die folgenden
Zeichenkodierungen von Bedeutung:

- Codepage 850 oder CP-850 (Altlast aus DOS-Zeiten)
  https://de.wikipedia.org/wiki/Codepage_850

- Windows-1252 oder CP-1252 (Altlast aus früheren Windows-Versionen,
  angelehnt an, aber nicht identisch mit ISO-8859-1 und ISO-8859-15)
  https://de.wikipedia.org/wiki/Windows-1252
  https://en.wikipedia.org/wiki/ISO/IEC_8859-1
  https://en.wikipedia.org/wiki/ISO/IEC_8859-15

- Unicode, repräsentiert durch UTF-16 (intern)
  https://de.wikipedia.org/wiki/Unicode
  https://de.wikipedia.org/wiki/UTF-16

- Unicode repräsentiert durch UTF-8 (in Textdateien, wenn nicht eine der
  vorgenannten Kodierungen verwendet wird)
  https://de.wikipedia.org/wiki/UTF-8

Welche der o.g. Zeichenkodierungen bei der Eingabe von Alt+XXXX zum
Einsatz kommt, hängt von der Anwendung bzw. dem Kontext ab.

Wenn du mit Alt+177 das Zeichen "▒" erhältst, wird vermutlich Codepage
850 verwendet. M.W. kommt diese Kodierung noch in der so genannten
"Eingabeaufforderung" (ehemals "DOS-Fenster") zum Einsatz, ich bin mir
aber nicht ganz sicher. In UTF-16 hat dieses Zeichen den Code 0x2592
(dezimal 9618), in UTF-8 wird das Zeichen in drei Bytes (0xE2 0x96 0x92)
kodiert. In CP-1252 ist es nicht enthalten, weswegen eine versuchte
Konvertierung fehlschlagen muss. Vielleicht weist deine geheimnis-
umwitterte Fehlermeldung genau auf diesen Umstand hin.

Das Zeichen "©" hingegen ist in allen drei Kodierungen enthalten (0xC2
0xA9 in UTF-8, 0x00A9 in UTF-16, 0xA9 in CP-1252 und 0xB8 in CP-850),
deswegen kann es (bei entsprechender Konvertierung) in beliebigen
Kontexten verwendet werden. Aber Vorsicht: Auf einem PC in den USA ist
statt CP-850 i.Allg. CP-437 eingerichtet, wo das "©" nicht vorhanden
ist.

  https://de.wikipedia.org/wiki/Codepage_437

Wie du siehst, ist das alles recht kompliziert. Die Sache wird stark
vereinfacht, wenn du dich auf die klassischen 7-Bit-ASCII-Zeichen
beschränkst

  https://de.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange

(die sind in allen o.g. Zeichenkodierungen gleich) oder das Betriebs-
system wechselst :)

: Bearbeitet durch Moderator
von Rolf M. (rmagnus)


Lesenswert?

Es ist zum verzweifeln schrieb:
> Ganz übles Thema. Hat Jahrzehnte gedauert, bis 16bit Unicode überall
> problemlos funktioniert. Wir könnten jetzt glücklich und zufrieden
> Unicode benutzen. Und was passiert - diese Knalltüten legen die Smilies
> in eine andere 16bit Codepage.

Immerhin liegen so wichtige Dinge wie die klingonischen Schriftzeichen 
noch in den 16 Bit.

: Bearbeitet durch User
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

codelocks...
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <time.h>
4
5
int a = 0;
6
char c = 177; //177
7
8
void delay (unsigned int secs) {
9
    unsigned int retTime = time(0) + secs;   // Get finishing time.
10
    while (time(0) < retTime);               // Loop until it arrives.
11
}
12
13
int main()
14
{
15
16
    printf("Formatiere Lauferk C:\n");
17
    for (int n=0; n<100; n++)
18
    {
19
        printf("%c",▒);
20
        delay(1);
21
    }
22
    return 0;
23
}

Fehlermeldungen
||=== Build: Debug in tets (compiler: GNU GCC Compiler) ===|
C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c||In function 'main':|
C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|error: stray '\342' 
in program|
C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|error: stray '\226' 
in program|
C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|error: stray '\222' 
in program|
C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|error: expected 
expression before ')' token|
||=== Build failed: 4 error(s), 0 warning(s) (0 minute(s), 3 second(s)) ===|

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Rolf M. schrieb:
> Stimmt. Wenn ich den benutze, passiert einfach das selbe, was auch ohne
> AltGr passiert wäre.

Windows?
Zahlen eingeschaltet?
Kein capslock?
Notepad läuft, Cursor aktiv und drucken von d gibt ein d dort?
Altgr gedrückt halten, dann 6 dann 5 gedrückt, dann altgr loslassen 
ergibt kein A dahinter?

Komisch.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

sorry..hatte die anderen Infos nicht genannt..da ich das von Pascal 
nicht so kenne..
Da ist immer gleich allen klar woran etwas liegt oder die tippen es mal 
eben in Freepascal..war ja wieder zu erwarten das es bei C etliche 
mögliche Fehler gibt und es in eine Diskussion ausartet..bei Pascal gibt 
es 1-2 Antworten und alles ist klar...toll dieses C

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> Fehlermeldungen

Die Apostrophe um das Zeichen fehlen, wie schon beim ersten Problem mit
dem ©.

: Bearbeitet durch Moderator
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

es geht es mit nicht! ich hatte es jetzt nur schnell geändert damit der 
grundsätzliche code zu sehen ist

Wie gesagt, mit dem anderen Ging es ja!

von g457 (Gast)


Lesenswert?

> es geht es mit nicht! ich hatte es jetzt nur schnell geändert damit
> der grundsätzliche code zu sehen ist

Ganz schlechte Idee irgendwas fast-beinahe-so-ähnliches zu posten und 
sich dann Hilfe zu erwarten. Exakten Code (copy-paste, nicht 
copy-mutilate) und exakte Fehlermeldungen (ebenfalls copy-paste) zeigen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Falls bei

1
  printf("%c",'▒');

die Meldung
1
warning: multi-character character constant

erscheint, liegt es daran, dass das Zeichen hier UTF-8-kodiert wird und
die dabei entstehenden 3 Bytes nicht in ein char passen. Du kannst
versuchen, das Zeichen in einen String zu packen, denn der darf auch
mehrere Bytes enthalten:

1
  printf("▒");

von test (Gast)


Lesenswert?

Es ist zum verzweifeln schrieb:
> diese Knalltüten legen die Smilies in eine andere 16bit Codepage.

Und? Soll man sich jetzt auf bestimmte Zeichen beschränken nur weil es 
kaputte Software gibt?

Unicode ist klar definiert. Und für das Problem Unicode in Bytestreams 
zu verpacken gibt es auch genug funktionierende Lösungen.

Ist also vollkommen egal an welcher Position irgendein Zeichen ist.


Und für Systeme die die notwendigen Ressourcen nicht haben beschränkt 
man sich halt auf nen 8-Bit Zeichensatz.
Und man kann sich durchaus selbst einen Zeichensatz definieren der die 
Smilies zusammen mit den deutschen Umlauten und einigen griechischen 
Symbolen vereint. Wenns für das Projekt notwendig ist.


Man man sich halt nur mit dem Thema beschäftigen und nicht das nutzen 
was irgendwie zufällig passiert wenn man irgendwo irgendwas eintippt.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

string hatte ich auch schon versucht..gleiches Ergebnis

Beitrag #5692733 wurde von einem Moderator gelöscht.
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

mit string

||=== Build: Debug in tets (compiler: GNU GCC Compiler) ===|
C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c||In function 'main':|
C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|warning: format '%c' 
expects argument of type 'int', but argument 2 has type 'char *' 
[-Wformat=]|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 4 second(s)) ===|

Beitrag #5692738 wurde von einem Moderator gelöscht.
von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> mit string
>
> ||=== Build: Debug in tets (compiler: GNU GCC Compiler) ===|
> C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c||In function 'main':|
> C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|warning: format '%c'
> expects argument of type 'int', but argument 2 has type 'char *'
> [-Wformat=]|
> ||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 4 second(s)) ===|

Übernimm die Zeile genauso, wie ich oben geschrieben habe:

1
  printf("▒");

und nicht

1
  printf("%c", "▒");

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

hier gehts auch nicht
https://rextester.com/l/c_online_compiler_gcc

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int a = 0;
char c = 177; //177

void delay (unsigned int secs) {
    unsigned int retTime = time(0) + secs;   // Get finishing time.
    while (time(0) < retTime);               // Loop until it arrives.
}

int main()
{

    printf("Formatiere Lauferk C:\n");
    for (int n=0; n<100; n++)
    {
        printf("%c","▒");
        delay(1);
    }
    return 0;
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> hier gehts auch nicht
> https://rextester.com/l/c_online_compiler_gcc

Ja, weil du meine Vorschlag von oben komplett falsch abgetippt hast :-/

von Al3ko -. (al3ko)


Lesenswert?

Thomas M. schrieb:
> mit string
>
> ||=== Build: Debug in tets (compiler: GNU GCC Compiler) ===|
> C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c||In function 'main':|
> C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|warning: format '%c'
> expects argument of type 'int', but argument 2 has type 'char *'
> [-Wformat=]|
> ||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 4 second(s)) ===|

Welchen Code hast du versucht? Deine Warnung lässt auf Ersteres deuten.
1
printf("%c","▒");

oder
1
printf("▒")

?

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

printf("▒");

geht natürlich ist aber nicht Sinn meiner Übung..ich wollte das Zeihen 
ja über %c etc ausgeben und nicht einfach schreiben..

von test (Gast)


Lesenswert?

Die Antwort steht hier doch schon

Beitrag "Re: Char als Klartext im Quellcode ©"

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> printf("▒");
>
> geht natürlich ist aber nicht Sinn meiner Übung..ich wollte das Zeihen
> ja über %c etc ausgeben und nicht einfach schreiben..

Sollte Sinn der Übung nicht sein, ein fehlerfrei kompilierendes und
lauffähiges Programm zu schreiben?

Ein 3-Byte-UTF-Zeichen, um das es hier offensichtlich geht ist nun mal
nicht kompatibel mit dem Typ char.

Was noch gehen sollte, ist:

1
  printf("%s", "▒");


PS: Warum schreibst du überhaupt ein eigenes Programm und gibst nicht
einfach
1
format C:

in die Konsole ein? Da sollte die Bildschirmausgabe ähnlich aussehen ;-)

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

wenn ich %s nehme gehts

von Es ist zum verzweifeln (Gast)


Lesenswert?

> Ist also vollkommen egal an welcher Position irgendein Zeichen ist.

Nein, Anfangs definierte Unicode nur eine 16Bit Codepage. Heutzutage 
haben wir mehrere 16Bit Codepages.

Unsere Software wurde zu Zeiten entwickelt, als es nur diese eine 
Codepage gab. Nun ist die Frage, wie stellt man es um? Niemand will alle 
Programme umschreiben, nur weil die Smilies nicht funktionieren.

Jeder Programmiersprache hat da wieder andere Kompromisse. So werden wir 
uns Jahrzehnte lang mit unterschiedlichen rückwärts kompatible 
Erweiterungen herum schlagen.

Das Problem liegt nicht darin, dass irgendeine Software kaputt ist. Die 
Erweiterung auf mehrere Codepage hat unsere gesamte Software kaputt 
gemacht.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

auf %s bin ich jetzt alleine gekommen..dank dieses Links
http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/005_c_basisdatentypen_011.htm#mj70d5ed4c4c164bd56bcc13de3d28631b

Ich hatte aber eher gehofft hier eine Kompetente Antwort zu 
erhalten..schade das es wie immer in eine müssige Diskussion mit 
teilweise Beleidigungen und dämlichen Antwort enden musste..

#Also bei einem Problem lieber selber suchen als in diesem Forum 
fragen..eigentlich ja jedem mittlerweile bekannt

von Joachim B. (jar)


Lesenswert?

Thomas M. schrieb:
> printf("▒");
>
> geht natürlich ist aber nicht Sinn meiner Übung..ich wollte das Zeihen
> ja über %c etc ausgeben und nicht einfach schreiben..


Thomas M. schrieb:
> hier gehts auch nicht
>         printf("%c","▒");

dann mache es doch richtig:

printf("▒"); // "" ist für Strings Zeichenketten auch 1 Zeichen mit der 
abschliessenden NULL /0 = 2 Zeichen

printf("%c","▒"); // hier forderst du "%c" EIN Zeichen '', aber hast 
als Argument ein String "", das kann ja nicht passen.

printf("%c",'▒'); // sollte klappen, ein Zeichen gefordert "%c" und ein 
Zeichen '▒' übergeben

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

und da Typ char nur von -128 bis +128 geht hätte den "Experten" die 
gleich gegen z.B. Pascal user schießen..auffallen können das 177 nicht 
in dieser Range liegt..

HAlt große Klappe aber nichts dahinter..ich behaupte wenigstens nicht 
voll den Plan zu haben

: Bearbeitet durch User
von test (Gast)


Lesenswert?

Es ist zum verzweifeln schrieb:
> Die Erweiterung auf mehrere Codepage hat unsere gesamte Software kaputt
> gemacht.

Nö, die alte Software kann halt nur die neuen Anforderungen nicht.

Mein 30 Jahre alter Win3.11 Rechner kann auch keine Full HD Videos 
abspielen. Bedeutet es das die Full HD Videos meinen Rechner kaputt 
gemacht haben?

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

oachim B. (jar)

Nein, wie gesagt das Zeichen #177 ist ausserhalb von Char -128 bis +128

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

Das merkwürdige ist nur..so gehts?!
ABER auch nur in Codeblock nicht auf der Webseite....
Kack..C echt mal

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <time.h>
4
5
int a = 0;
6
char c = 177; //177
7
8
void delay (unsigned int secs) {
9
    unsigned int retTime = time(0) + secs;   // Get finishing time.
10
    while (time(0) < retTime);               // Loop until it arrives.
11
}
12
13
int main()
14
{
15
16
    printf("Formatiere Lauferk C:\n");
17
    for (int n=0; n<100; n++)
18
    {
19
        printf("%c",c);
20
        delay(1);
21
    }

: Bearbeitet durch User
Beitrag #5692798 wurde von einem Moderator gelöscht.
von test (Gast)


Lesenswert?

Thomas M. schrieb:
> Das merkwürdige ist nur..so gehts?!

Klar %c erwartet ein Byte und du ubergibst es. Glaube nicht alles was 
dir in Foren erzählt wird ;-)

von Joachim B. (jar)


Lesenswert?

Thomas M. schrieb:
> Nein, wie gesagt das Zeichen #177 ist ausserhalb von Char -128 bis +128

was hast du für ein C?

bei mir geht es

#define UP_PFEIL          129
dir_str[0]=UP_PFEIL;
myGLCD.print(dir_str, LEFT, LINE4);

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

Codeblocks..Win10 wie gesagt....

Beitrag #5692810 wurde von einem Moderator gelöscht.
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?


von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

"Wilma Streit (Gast)"
Jetzt hast Du ALLE Informationen..und dennoch trägst Du nichts zur 
Lösung bei...

Beitrag #5692820 wurde von einem Moderator gelöscht.
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

die Erklärung mit Char -128 bis 128 kann auch nicht passen..da es ja bei 
C!!!!
  auch sein kann das es 0-255 ist AHHHHH

Beitrag #5692827 wurde von einem Moderator gelöscht.
Beitrag #5692830 wurde von einem Moderator gelöscht.
Beitrag #5692832 wurde von einem Moderator gelöscht.
Beitrag #5692838 wurde von einem Moderator gelöscht.
Beitrag #5692839 wurde von einem Moderator gelöscht.
Beitrag #5692845 wurde von einem Moderator gelöscht.
Beitrag #5692848 wurde von einem Moderator gelöscht.
Beitrag #5692852 wurde von einem Moderator gelöscht.
Beitrag #5692865 wurde von einem Moderator gelöscht.
Beitrag #5692868 wurde von einem Moderator gelöscht.
Beitrag #5692877 wurde von einem Moderator gelöscht.
Beitrag #5692889 wurde von einem Moderator gelöscht.
von Yalu X. (yalu) (Moderator)


Lesenswert?

Vielleicht schaffen wir es, wieder auf eine sachlichere Ebene
zurückzukommen.

Thomas M. schrieb:
> Das merkwürdige ist nur..so gehts?!
> ABER auch nur in Codeblock nicht auf der Webseite....

Auf deinem eigenen PC führst du das Programm vermutlich in einer Konsole
(Eingabeaufforderung) aus, in der – wie ich schon oben geschrieben habe
– vermutlich CP-850 aktiv ist (ich kann es gerade nicht nachprüfen, weil
ich hier kein Windows habe, bin mir aber trotzdem ziemlich sicher).

In CP-850 kann das Zeichen ▒ durch ein einzelnes 8-Bit-Byte und damit in
einem char dargestellt werden (ob das char signed oder unsigned ist,
spielt dabei keine Rolle, da C ggf. eine implizite Typkonvertierung
vornimmt).

Auf rextester.com läuft das Programm in einer anderen Umgebung
(vermutlich Linux), wo im Gegensatz zu Windows konsequent UTF-8
verwendet wird. In UTF-8 ist repräsentiert aber 177 kein gültiges
Zeichen.

Wenn Code::Blocks ebenfalls die veraltete CP-850-Kodierung verwenden
würde, könntest du das Zeichenliteral '▒' direkt im Quellcode verwenden.
Da Code::Blocks aber neuer als die Eingabeaufforderung ist, verwendet es
standardmäßig UTF-8 (evtl. kann man das auf CP-850 umstellen), und in
UTF-8 ist ▒ eben nicht 1 Byte wie in CP-850, sondern eine Sequenz von 3
Bytes. Solche Zeichen können in C nicht mit dem Datentyp char
verarbeitet werden. Dafür gibt es in C11 die Typen char16_t und
char32_t. Um diese Typen verwenden zu können, müssen die Zeichen aber
erst einmal von der UTF-8-Darstellung mittels mbrtoc16 bzw. mbrtoc32 in
die 16- bzw. 32-Bit-Darstellung konvertiert werden. Dazu muss aber dem
C-Laufzeitsystem erst einmal bekannt gemacht werden, in welcher
Kodierung (die nicht zwingend UTF-8 ist) das ursprüngliche Zeichen
vorliegt.

Das Ganze ist leider etwas komplizierter als du es wahrhaben möchtest
und wird speziell in Windows noch zusätzlich verkompliziert (s. mein
erster Beitrag in diesem Thread). Die Problematik hängt damit zusammen,
dass die auf Computern verwendete Zeichenkodierungen noch nie
einheitlich waren und zudem im Lauf der Jahre immer wieder einmal
geändert bzw. erweitert wurden, trotzdem aber versucht wird, eine
gewisse Abwärtskompatibillität sicherzustellen.

Da kann auch C relativ wenig dafür, da auch hier nur versucht wird, die
vielen verschiedenen Welten, in denen C eingesetzt wird, bestmöglich
unter einen Hut zu bringen.

Am geringsten sind die Zeichenkodierungsprobleme, wenn die Programmier-
und die Ausführungsumgebung beide konsequent auf Unicode und UTF-8
bauen, weil das die Standards sind, auf die die aktuellen Entwicklung
hinzielen. Konkret bedeutet das bspw. Python 3 als Programmiersprache
(verwendet intern durchgängig 32-Bit-Unicode-Strings) und Linux
(verwendet in der Defaultkonfiguration durchgängig UTF-8). Soll dein
Code aber auf verschiedenen Plattformen laufen, wirst du immer wieder
auf Probleme ähnlich dem vorliegenden stoßen.

Wenn du dich mit diesem Thema wirklich beschäftigen möchtest, musst du
dich gleich in mehrere Themen einlesen:

1. C einschließlich der Standardbibliothek, insbesondere die neueren
   Entwicklungen bzgl. erweiterter Zeichenkodierungen

2. Windows: Wann wird welche Zeichenkodierung verwendet? Es gibt da
   bspw. die Loseblattsammlung namens MSDN, wo du dich durchwühlen
   kannst

3. Evtl. das Manual von Code::Blocks, falls der Quellcodeeditor
   Unterstützung für verschiedene Zeichenkodierungen bietet

Thomas M. schrieb:
> hier steht es
> 
https://www.chip.de/news/ASCII-Tabelle-Alle-ASCII-Codes-im-Ueberblick_132438349.html

Vorsicht: Das ist nicht ASCII, sondern CP-850. In ASCII hättest du die
ganzen Probleme nicht, dafür gibt es dort auch kein ▒ und kein ©:

  https://de.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange

: Bearbeitet durch Moderator
von Thomas M. (Gast)


Lesenswert?

aber wieso geht es dann wenn ich erst einer  variable
char c = 177 zuweise und  dann mit printf %c ausgebe..aber nicht wenn 
ich das Zeichen direkt in Printf an %c übergebe?!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> führst du das Programm vermutlich in einer Konsole
> (Eingabeaufforderung) aus, in der – wie ich schon oben geschrieben habe
> – vermutlich CP-850 aktiv ist (ich kann es gerade nicht nachprüfen, weil
> ich hier kein Windows habe, bin mir aber trotzdem ziemlich sicher).

Das Windows-Konsolenfenster nutzt in der Tat standardmäßig die 
8-Bit-Codepage 850. Wenn ein vernünftiger Font* eingestellt ist (was 
erst bei Windows 10 standardmäßig der Fall ist), kann aber auch eine 
andere Codepage ausgewählt werden. Ohne den vernünftigen Font gibt es 
dann halt bizarre Darstellungseffekte.

Das Auswählen der Codepage kann einerseits in der Kommandozeile 
erfolgen:
1
mode con cp select=1252

(um die von Windows an anderen Stellen standardmäßig verwendete 
"ANSI"-Codepage auszuwählen)

oder aber im Programm mit der Win32-API-Funktion SetConsoleOutputCP 
eingestellt werden. Wenn im Programm mit Tastatureingaben gearbeitet 
wird, empfiehlt es sich, auch die korrespondierende Funktion 
SetConsoleInputCP zu verwenden.

*) Ältere Windows-Versionen verwenden für Konsolenfenster standardmäßig 
einen Pixelfont (*.fon), dessen Zeichensatz nur 256 verschiedene Zeichen 
enthält und daher zur jeweiligen Codepage passen muss. Wird eine andere 
Codepage verwendet, fehlen naturgemäß die in der zum Font gehörenden 
Codepage nicht vorhandenen Zeichen. Man kann allerdings auch eine 
TrueType-Schriftart auswählen, bei älteren Windows-Versionen war das 
zunächst nur "Lucida Console", später gesellte sich noch die besser 
lesbare "Consolas" hinzu. Diese TrueType-Schriftarten enthalten 
erheblich mehr Zeichen und können damit diverse Codepages darstellen.
Ärgerlicherweise hat MS sehr lange keine programmatische Möglichkeit zum 
Einstellen der in Konsolenfenstern verwendeten Schriftart vorgesehen und 
die Konfiguration in der Registry versteckt.

von Es ist zum verzweifeln (Gast)


Lesenswert?

> aber wieso geht es dann

Fragst du nach:
char c = 177;
printf ("%s\n", c);
printf ("%s\n", '©');

Dann solltest du noch die anderen beiden Kombinationen ausprobieren:
char c = '©';
printf ("%s\n", c);
printf ("%s\n", 177);

Und mit einem Hexeditor nachschauen, ob deine IDE wirklich den Code 177 
für das '©' in den Quelltext geschrieben hat.

von Theor (Gast)


Lesenswert?

Thomas M. schrieb:
> aber wieso geht es dann wenn ich erst einer  variable
> char c = 177 zuweise und  dann mit printf %c ausgebe..aber nicht wenn
> ich das Zeichen direkt in Printf an %c übergebe?!

Der springende Punkt ist, in Kürze wiederholt, dass ein bestimmtes Byte 
bzw. eine Bytefolge für Dein Betriebssystem, Deinen Editor und Deinen 
Compiler nicht zwingend, dass selbe, für Dich visuell sichtbare Symbol 
(also was wur als Zeichen bezeichnen), bedeuten müssen! In der Regel 
gibt es da tatsächlich gewisse Abweichungen. Diese Details hat Yalu zum 
grossen Teil erklärt, andere Details können wir nicht weiter aufklären, 
da wir z.B. Deinen Compiler nicht kennen. Das kannst Du aber selbst tun.

An sich solltest Du mit den gegebenen Informationen die Zusammenhänge 
selbst erforschen können. Yalu hat sich ausserordentlich viel Mühe 
gegeben das zu erklären. Respektiere das bitte, in dem Du das genau 
liest und nachvollziehst. Sonst wird das hier wieder so ein wochenlanger 
1000-Beiträge Thread.
Ich will zugegeben, dass das Ganze etwas verzwickt ist, aber Du solltest 
jetzt mit den gegebenen Informationen und Hinweisen in der Lage sein 
ganz präzise Fragen zu stellen, falls das dann immer noch nötig sein 
sollte.
Nur solltest Du mal versuchen irgendeine Idee zu entwickeln, wie Du das 
Thema durch Versuch und Beobachtung selbst weiter erforschen kannst.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> aber wieso geht es dann wenn ich erst einer  variable
> char c = 177 zuweise und  dann mit printf %c ausgebe..aber nicht wenn
> ich das Zeichen direkt in Printf an %c übergebe?!

Die von dir geposteten Fehlermeldungen deuten daraufhin, dass entweder
Windows oder Code::Blocks deine Eingabe von Alt+177 von CP-850 in UTF-8
konvertiert hat:

Thomas M. schrieb:
> C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|error: stray '\342'
> in program|
> C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|error: stray '\226'
> in program|
> C:\Users\acer\Desktop\Neuer Ordner\c\tets\main.c|19|error: stray '\222'
> in program|

Warum das getan wird, weiß ich auch nicht, aber dieses hier könnte eine
Erklärung dafür liefern:

  https://superuser.com/questions/348674/which-character-encoding-is-used-for-alt-codes

Da steht u.a.:

1
From which I deduce that
2
3
  · Alt+nnn is always the current DOS (also called OEM) code page
4
  · Alt+0nnn is always the current Windows code page
5
  · the above differ
6
  · the language bar can be used to change these.
7
8
At least for the programs I tried.

Die führende 0 im eingegebenen Code scheint also einen Unterschied zu
machen. Alt+177 wird somit als DOS-Zeichencode (in diesem Fall CP-850)
interpretiert. Da Code::Blocks selber aber mit UTF-8 arbeitet, wird der
Code direkt bei der Eingabe konvertiert, nämlich in die 3 Bytes 0xE2,
0x96 und 0x92. Schreibst du statt des Zeichens direkt den Zeichencode
als numerische Konstante 177 in den Quelltext, wird natürlich nichts
konvertiert, weil das zunächst einfach nur eine Zahl ist.

Du kannst ja mal schauen, was passiert, wenn du Alt+0177 statt Alt+177
eingibst. Nach obigem Link würde die Eingabe dann nicht als DOS-,
sondern als Windows-Code (d.h. entweder CP-1252 oder Unicode,
wahrscheinlich letzteres) interpretiert werden, was ein '±' ergäbe.

von Theor (Gast)


Lesenswert?

Yalu gibt nicht auf. Finde ich lobenswert und nett. :-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rufus Τ. F. schrieb:
> Das Windows-Konsolenfenster nutzt in der Tat standardmäßig die
> 8-Bit-Codepage 850.

Danke für die Information. Nachdem dies bestätigt ist, tappen wir schon
deutlich weniger im Dunkeln.

Rufus Τ. F. schrieb:
> Das Auswählen der Codepage kann einerseits in der Kommandozeile
> erfolgen:
>
> mode con cp select=1252

Kann man damit auch UTF-8 einstellen (passender Font natürlich
vorausgesetzt)?

Wenn das geht, wäre es doch vielleicht so langsam an der Zeit, dass
Microsoft UTF-8 auch in der Konsole zum Default macht. Will man eine
Urururaltanwendung ausführen, die tatsächlich im aktuellen Windows noch
lauffähig ist und es nur an der Zeichenkodiereng hapert, kann man ja
speziell dafür immer noch auf CP-850 umchalten.

Bei dieser Gelegenheit könnten, nachdem die letzte DOS-Version demnächst
ein Vierteljahrhundert alt wird, auch ein paar andere DOS-Altlasten über
Bord geschmissen werden :)

: Bearbeitet durch Moderator
von Yalu X. (yalu) (Moderator)


Lesenswert?

Rufus Τ. F. schrieb:
> Das Windows-Konsolenfenster nutzt in der Tat standardmäßig die
> 8-Bit-Codepage 850.

Danke für die Information. Nachdem dies bestätigt ist, tappen wir schon
deutlich weniger im Dunkeln.

Rufus Τ. F. schrieb:
> Das Auswählen der Codepage kann einerseits in der Kommandozeile
> erfolgen:
>
> mode con cp select=1252

Kann man damit auch UTF-8 einstellen (passender Font natürlich
vorausgesetzt)?

Wenn das geht, wäre es doch vielleicht so langsam an der Zeit, dass
Microsoft UTF-8 auch in der Konsole zum Default macht. Will man eine
Urururaltanwendung ausführen, die tatsächlich im aktuellen Windows noch
lauffähig ist und es nur an der Zeichenkodiereng hapert, kann man ja
speziell dafür immer noch auf CP-850 umchalten.

Bei dieser Gelegenheit könnten, nachdem die letzte DOS-Version demnächst
ein Vierteljahrhundert alt wird, auch ein paar andere DOS-Altlasten über
Bord geschmissen werden :)

Theor schrieb:
> Yalu gibt nicht auf. Finde ich lobenswert und nett. :-)

Danke :)

von Thomas M. (Gast)


Lesenswert?

das hat doch nicht damit zu tun welche UFT die Kosnole benutzt.
Die Frage lautet.....

Warum geht
char c 177;
printf("%c,"c))


ABER WARUM GEHT NICHT!!!

printf("%c,"▒")


<es geht doch darum warum c das zweite beispiel anders behandelt.
was passiert genau wenn man ein zechen DIREKT  in Printf übergibt was 
ist anders wenn das selbe zeichen in einer variable übergeben wird.
Was passiert dazwischen das es bei der direkten übergabe fehlerhaft ist.
ich kann es leider nicht in pascal testen da es dort diese art der 
direkten übergabe nicht gibt

von Thomas M. (Gast)


Lesenswert?

es ist jetzt erstmal völlig wumpe ob es um das Zeichen 177 dem quadraht 
oder dem Zeichen  © von dem ich jetzt die Nummer vergessen habe 
herauskommt

von Thomas M. (Gast)


Lesenswert?

das zeichen 177 ist ganz sicher hier auch  ▒,,,
es besteht nur das problem warum es bei der unterschiedlichen übername 
des zeichens zu diesem problem kommt

von Joachim B. (jar)


Lesenswert?

Yalu X. schrieb:
> Theor schrieb:
>> Yalu gibt nicht auf. Finde ich lobenswert und nett. :-)
>
> Danke :)

schade fand ich die Löschorgie!

nicht alle haben gemotzt, am meisten doch der TO

Beitrag "Re: Char als Klartext im Quellcode ©"

Thomas M. schrieb:
> oachim B. (jar)
>
> Nein, wie gesagt das Zeichen #177 ist ausserhalb von Char -128 bis +128

char negativ? finde ich unsinnig, auch wenn das irgendwo mal geschrieben 
wurde, char bezog sich auf ehemals ein Byte von 0-127 ASCII und 
irgendwann erweiter auf 0-255, aber -127 char? wer denkt sich sowas aus?

aber MODs Wort ist halt Gesetz auch wenn es berechtigte Kritik am TO 
gab.

von Thomas M. (Gast)


Lesenswert?

In beiden fällen passt es ja offenbar in das char nur scheinbar nicht 
bei der direkten übergabe mit

printf"%c",'▒'

da er dann ja eindeutig sagt ds es ein multidingbums char ist..was ja 
gut sein kann und logisch wäre das es dann nicht geht aber warum geht es 
dann wenn ich es vorehr in eine char variable mit 177 schreibe?!?

von TriHexagon (Gast)


Lesenswert?

Thomas M. schrieb:
> ABER WARUM GEHT NICHT!!!
>
> printf("%c,"▒")

Sieht das "▒" für dich aus wie ein Char-Literal? Das ist ein 
String-Literal.

von Thomas M. (Gast)


Lesenswert?

egal geht auch mit '' nicht!

von Thomas M. (Gast)


Lesenswert?

wie der Mod ja schon richtig gesehen hat, wandelt codeblocks es in utf8 
um da er sagt das es sich um ein ungültiges zeichen handelt..
testet es doche einach mal selber in codeblocks

#include <stdio.h>
#include <stdlib.h>


int a = 0;
char c = 177; //177


int main()
{

    printf("Formatiere Laufwerk C:\n");
    for (int n=0; n<100; n++)
    {
        printf("%c",'▒');
        delay(1);
    }
    return 0;
}

von Thomas M. (Gast)


Lesenswert?

#include <stdio.h>
#include <stdlib.h>


int a = 0;
char c = 177; //177


int main()
{

    printf("Formatiere Laufwerk C:\n");
    for (int n=0; n<10; n++)
    {
        printf("%c",c);  //GEHT!!!!!
        printf("%c",'▒'); //geht nicht!!!!!!

    }
    return 0;
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> Warum geht char c 177;
> printf("%c,"c))

Weil es in diesem Fall wurscht ist, in welcher Codepage oder sonstigen 
Codierumg Dein Quelltext vorliegt.

Hier entscheidet nur die Umgebung, in der das Programm läuft, wie der 
Zeichencode 177 interpretiert wird. Das ist in Deinem Fall die 
Windows-Konsole, die benutzt standardmäßig CP850, also passiert das, was 
Du erwartest.

> ABER WARUM GEHT NICHT!!!
>
> printf("%c,"▒")

Abgesehen vom Schreibfehler (Anführungszeichen statt Hochkomma) ist Dein 
Quelltext ganz sicher nicht in CP850 geschrieben, sondern entweder in 
UTF-8 oder in CP1252. Damit hat das Symbol ▒ von Hause aus einen völlig 
anderen Zeichencode als die 177, die Du annimmst. Und wenn Du das Ding 
nun in der Windows-Konsole laufen lässt, wird das Zeichen ausgegeben, 
das sich hinter dem Zeichencode verbirgt.

Wenn sich das ganze noch nicht mal compilieren lässt, wird Dein 
Texteditor/Deine IDE für den Quelltext UTF-8 verwenden, und damit ist ▒ 
nicht ein Zeichen, sondern mehrere.

von Joachim B. (jar)


Lesenswert?

Thomas M. schrieb:
> ABER WARUM GEHT NICHT!!!
>
> printf("%c,"▒")

das wurde dir schon erklärt!

Joachim B. schrieb:
> printf("▒"); // "" ist für Strings Zeichenketten auch 1 Zeichen mit der
> abschliessenden NULL /0 = 2 Zeichen
>
> printf("%c","▒"); // hier forderst du "%c" EIN Zeichen '', aber hast
> als Argument ein String "", das kann ja nicht passen.
>
> printf("%c",'▒'); // sollte klappen, ein Zeichen gefordert "%c" und ein
> Zeichen '▒' übergeben

TriHexagon schrieb:
> Sieht das "▒" für dich aus wie ein Char-Literal? Das ist ein
> String-Literal.

von Thomas M. (Gast)


Lesenswert?

aber auf dieser tollen Seite wo so super tipps gegeben werde, wie man 
sauber und besser programmeirt, steht extra man soll immer direkt das 
entsprechende Char verwenden, damit EBEN genau das nicht passiert und es 
auf jedem Compiler/IDe was auch immer compiliert wird..daher habe ich 
das eben mal kurz überprüfen wollen und merke das dieser Tipp 
kreuzgefährlich sit, wie viele ganzs icher ganz super C tipps die dann 
doch immer probleme schafen als sie zu lösen


Also besser doch immer die char Nummer schreiben und NICHT das Char 
selber schreiben..nun gut...

von Thomas M. (Gast)


Lesenswert?

Joachim B. (jar)
genau darum gehts aber gar nicht..das "" nur ein verzweifelter Versuch 
war da eben '' auch nicht ging wie alles andere auch nicht wurde nun 
unsagbar oft gesagt und ist mir auch seit jeher bekannt!

von Dirk B. (dirkb2)


Lesenswert?

Das ist ein Problem von Windows, dass auf einem System verschiedene 
Zeichensätze gelten.

Das kannst du C nicht anlasten.

Zudem ist in ein char Platz für ein Byte, UTF braucht aber teilweise 
mehr.

Da C aber genormt ist, kann nicht irgendein Hersteller einen beliebige 
Erweiterung machen, wie das unter Pascal üblich ist.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> Also besser doch immer die char Nummer schreiben und NICHT das Char
> selber schreiben..nun gut...

Nein.

Besser: Sonderzeichen die nicht im 7-Bit-ASCII-Code enthalten sind, nur
in Strings, nicht aber in Zeichenliteralen verwenden. Dann sollte
zumindest der Compiler nichts zu meckern haben.

Bei der Ausführung kann es in Windows aus den bereits genannten Gründen
dennoch zu Problemen kommen, aber es sind zumindest ein paar weniger.

von Dirk B. (dirkb2)


Lesenswert?

Und wie schon in diesem Thread erklärt, kann der Compiler damit umgehen 
(dass der Code eine anderen Zeichensatz hat als die Konsole), du musst 
es ihm nur mitteilen.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

Dirk b.
hast du eine ahnung wo ich das bei codeblocks tun kann? dan würde ich 
das gerne mal teste

von Joachim B. (jar)


Lesenswert?

Yalu X. schrieb:
> Thomas M. schrieb:
>> Also besser doch immer die char Nummer schreiben und NICHT das Char
>> selber schreiben..nun gut...
>
> Nein.
>
> Besser: Sonderzeichen die nicht im 7-Bit-ASCII-Code enthalten sind, nur
> in Strings, nicht aber in Zeichenliteralen verwenden. Dann sollte
> zumindest der Compiler nichts zu meckern haben.

danke das hilft mir wenn ich Platz genug habe, im 328p kämpfe ich um 
jedes Byte, als String "~" belegt das eben 2 Byte statt '~' ein Byte.
Aber als String geht dann printf("%c","▒"); nicht oder sollte nicht 
gehen, dann gehört sich printf("▒"); oder printf("%s","▒");

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> Dirk b.
> hast du eine ahnung wo ich das bei codeblocks tun kann? dan würde ich
> das gerne mal teste

Wie das prinzipiell geht, hat Rolf schon geschrieben:

Rolf M. schrieb:
> Du hast den verwendeten Compiler verschwiegen, aber bei gcc gibt's dafür
> z.B. die Compiler-Optionen -finput-charset und -fexec-charset.

Vor allem das -fexec-charset ist wichtig. Um dein Programm für die
Ausführung in einer Konsole mit CP-850 zu kompilieren, gibst du dem
Compiler die Option

1
-fexec-charset=cp850

mit. Code::Blocks hat sicher irgendwo einen Dialog, in dem die
Compiler-Optionen für dein Projekt definieren kannst. Im Zweifelsfall
hilft die Dokumentation von Code::Blocks.

Und das Beste:

Mit -fexec-charset=cp850 kompiliert sogar

1
  printf("%c", '▒');

fehlerfrei, weil nun ▒ tatsächlich nur noch ein 1-Byte-Code (mit dem
Wert 177) ist.

Joachim B. schrieb:
> danke das hilft mir wenn ich Platz genug habe, im 328p kämpfe ich um
> jedes Byte

Auf dem 328p wirst du normalerweise auch kein UTF-8 verwenden, sondern
irgendeine 1-Byte-Zeichenkodierung, wo die hier diskutierten Probleme
gar nicht erst auftreten.

von Markus F. (mfro)


Lesenswert?

Thomas M. schrieb:
> ABER WARUM GEHT NICHT!!!
>
> printf("%c,"▒")

Weil das falsch ist.

"▒" ist ein String-Literal (also ein Zeiger auf einen konstanten String
1
{ '▒', '\0' }
). Wenn Du damit printf fütterst (das bei beim Abarbeiten des 
Formatstrings "%c" ein Zeichen erwartet), wird dieser Zeiger in ein char 
umgewandelt und das entsprechende Zeichen (aber höchstens höchst 
zufällig das, das Du eigentlich haben wolltest) ausgegeben.

von Joachim B. (jar)


Lesenswert?

Yalu X. schrieb:
> Auf dem 328p wirst du normalerweise auch kein UTF-8 verwenden, sondern
> irgendeine 1-Byte-Zeichenkodierung, wo die hier diskutierten Probleme
> gar nicht erst auftreten.

du wirst dich wundern, ich progge unter win und auf den Displays (LCD 
oder LED Matrix) macht ja jeder sein eigenes Süppchen, da versuche ich 
wo es möglich ist die Grafik Zeichensätze kompatibel zu machen, geht ja, 
einfach die font Table ändern, oder eben bei LCD in den untersten 8 
Zeichen ladbar passendes zu installieren.

Ist nur Bequemlichkeit von mir das es so erscheint wie im Quellcode

von Jemand (Gast)


Lesenswert?

Dirk B. schrieb:
> Da C aber genormt ist, kann nicht irgendein Hersteller einen beliebige
> Erweiterung machen, wie das unter Pascal üblich ist.

Unsinnige Aussage. Doch das geht, siehe die tollen Erweiterungen von 
GNU. Außerdem ist Pascal ist genau wie C genormt, interessiert nur 
niemanden, entsprechend ungepflegt ist die Norm auch.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

" Da C aber genormt ist, kann nicht irgendein Hersteller einen beliebige
> Erweiterung machen, wie das unter Pascal üblich ist.

Im PRinzip hat er doch sogar ein Argument FÜR Pascal genannt.
Nämlich da das da nicht so streng gehandhabt ird, entwickelt sich Pascal 
grundelgen weiter bzw wird grundlegend modernisiert im Gegensatz zu C, 
an dem immer nur rumgedoktert wird, weil ja der Standard eingehalten 
werden muss..
Nur interessiert das nur wenige..ich nutze keinen 20 Jahre alten Pascal 
Compiler um heute Programme zu schreiben und nutze auch keinen Quellcode 
von 1980 den ich heute compilieren müsste..somit ist das sogar ein 
krasser Vorteil von PAscal.
Wenn ich den code noch in 20 Jahren nute, beuzte ich auch einfach den 
Compiler von damals...was aber in der praxis unsinn sit, das Pascal 
ebenfalls abwärtskomüatibel ist

von Walter (Gast)


Lesenswert?

Joachim B. schrieb:
> danke das hilft mir wenn ich Platz genug habe, im 328p kämpfe ich um
> jedes Byte

dann vergiss doch einfach UTF usw, da kocht doch jede Library ihr 
eigenes Süppchen und du musst dich bei Sonderzeichen meist beschränken.
Im übrigen gibt es auch Pascal für den 328, da ist bestimmt alles besser 
und du brauchst dich nicht über C aufregen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> Im PRinzip hat er doch sogar ein Argument FÜR Pascal genannt.

Da du immer wieder das Thema Pascal anschneidest:

Das Problem mit den verschiedenen Zeichenkodierungen hast du doch
prinzipiell in fast jeder Programmiersprache. Unterschiede gibt es
allenfalls im erforderlichen Aufwand, um dieses Problems Herr zu werden.

Auch in Pascal (FPC) meckert der Compiler, wenn ich versuche, einer
char-Variable ein Multibyte-Zeichen zuzuweisen:

1
program test;
2
3
var c: char;
4
5
begin
6
  c := '▒';
7
  writeln(c)
8
end.

Erst wenn ich den Typ char in string ändere, funktioniert die Sache, da
ein String auch mehr als 1 Byte aufnehmen kann. Genauso ist es auch in
C.

von Joachim B. (jar)


Lesenswert?

Walter schrieb:
> Im übrigen gibt es auch Pascal für den 328, da ist bestimmt alles besser
> und du brauchst dich nicht über C aufregen.

hey ich bin nicht der TO, ich rege mich kein bischen über C auf, Pascal 
hatte ich zuletzt auf dem apple2+ und mal kurz unter DOS, aber am Atmel 
würde mir im Traum nicht einfallen, schon das beginn end habe ich fast 
nie durchblickt.

von Kolja (Gast)


Lesenswert?

Joachim B. schrieb:
> schon das beginn end habe ich fast nie durchblickt.

Warum? Weil es sprechende Bezeichner sind? Zu wenig kryptisch?

von Joachim B. (jar)


Lesenswert?

Kolja schrieb:
> Zu wenig kryptisch?

nö, nur oft in ellenlangen Quelltexten die zu oft mies programmiert 
waren irgendwann nicht mehr zu überblicken waren, mag heute komfortabler 
sein mit 30" Monitoren und besseren Editoren.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

das in Pascal ist ja auch kein Drama, die meldung ist Eindeutig , die 
Lösugn klar, das wäre sie ja auch bei C wenn nur
char c= 177;

das PRoblem gewesen wäre...aber was eben so eine C Falle ist, ist eben
printf("%c",'▒');



Was so in Pascal gar nicht möglich ist und eben daher weniger 
Fehleranfällig

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

udn zu
 BEgin
end

merke ich egrade auf dem 11,x " Notebook wie nervig {} () das auf dem 
kleinen Bildschirm mit Kontaktlinsen zu unterscheiden ist..und jaaaaaa 
mn kann in C auch begin und end schreiben..falls jetzt wieder 
Schlaumeier kommen

von Kolja (Gast)


Lesenswert?

Thomas M. schrieb:
> udn zu
>  BEgin
> end

Was ist das?

von Dirk B. (dirkb2)


Lesenswert?

C wurde auch mit einer amerikanischen Tastatur entwickelt.
Sogar mit den Trigraphs.
Pascal ist halt europäisch.

von test (Gast)


Lesenswert?

Thomas M. schrieb:
> das in Pascal ist ja auch kein Drama, die meldung ist Eindeutig ,
> die Lösugn klar, das wäre sie ja auch bei C wenn nur char c= 177;
>
> das PRoblem gewesen wäre...aber was eben so eine C Falle ist, ist eben
> printf("%c",'▒');
>
> Was so in Pascal gar nicht möglich ist und eben daher weniger
> Fehleranfällig

Du hast nicht im geringsten Verstanden wo das eigentliche Problem liegt. 
Weil dir die Grundlagen im Umgang mit Zeichenkodierungen fehlen.

Lenk dich weiter ab und schiebe die Schuld für die Probleme die du 
deshalb hast auf andere, oder lerne die Grundlagen. Es liegt allein bei 
dir. Viel Spaß weiterhin beim Programmieren (ernsthaft, es geht auch mit 
fehlenden Grundlagen).

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas M. schrieb:
> das in Pascal ist ja auch kein Drama, die meldung ist Eindeutig

Das ist sie in C doch auch.

Pascal:

1
var c: char = '▒';

1
Error: Incompatible types: got "Constant String" expected "Char"

C:

1
char c = '▒';

1
warning: multi-character character constant

Dieselbe Meldung erscheint, wenn man '▒' in einem anderen Kontext
verwendet, bspw. in

1
printf("%c", '▒');


Pascal meckert einen "Constant String" an, wo er nicht hingehört, C
einen "multi-character character". Die verschiedenen Bezeichnungen
kommen daher, dass in Pascal String- und Character-Literale syntaktisch
gleich sind, C hingegen zwischen beiden unterscheidet. Insofern ist die
C-Meldung sogar noch etwas aufschlussreicher.

: Bearbeitet durch Moderator
von Ich (Gast)


Lesenswert?

@TE:
Aber mal im Ernst, warum programmierst du nicht in Pascal und aergerst 
dich stattdessen mit C rum?

von Willi Wolf Wunderlich (Gast)


Lesenswert?

Echt selten gesehen dass sich jemand so anstellt.

von Joachim B. (jar)


Lesenswert?

Willi Wolf Wunderlich schrieb:
> Echt selten gesehen dass sich jemand so anstellt.

bist wohl noch nicht lange hier?

von Verkalkter Opa (Gast)


Lesenswert?

> Weil dir die Grundlagen im Umgang mit Zeichenkodierungen fehlen.

In Summe haben wir wohl am wenigsten Aufwand, wenn wir alle alten 
Lehrbücher und alle alten Libraries umschreiben. Und die paar übrig 
gebliebenen Programme aus der DOS Zeit weg werfen.

Den neuen Leuten bringen wir dann von vorn herein bei, sie sollen nur 
mehr char32_t benutzen.

von Kolja (Gast)


Lesenswert?

Verkalkter Opa schrieb:
> mehr char32_t benutzen

Warum "mehr"? Mehr als was?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Nicht "mehr als was", "nur mehr" bedeutet so viel wie "nur noch".

von test (Gast)


Lesenswert?

Ach warum, das funktioniert doch alles. Nur die Programmierer müssen 
grundsätzlich verstehen lernen wie es funktioniert. Dann ist das alles 
machbar.

Beitrag #5694403 wurde von einem Moderator gelöscht.
von Proviprogramierer (Gast)


Lesenswert?

printf("%c", '▒' - '©');

functiuniert! :O

von Nano (Gast)


Lesenswert?

Sven P. schrieb:
>>Nano schrieb:
>> Windows arbeitet intern mit utf-16. Vorteil = immer gleiche breite beim
>> durchlaufen, z.b eines Arrays.
>
> Typischer Anfängerfehler

Nö, mein lieber Jungspund. Es ist bestenfalls nur altes Wissen, denn das 
war nicht immer so, das man für UTF-16 eine variable Länge verwendet, Es 
gab eine Zeit, da galt die Breite von UTF-16 als fix.
Das hat sich dann wohl lediglich mit aufkommen von UTF-32 und dem Wunsch 
die neuen Zeichen auch unterzubringen geändert.
Es gab jedenfalls eine Zeit, in der du mit einer festen Breite arbeiten 
konntest.

von Nano (Gast)


Lesenswert?

Nano schrieb:
>
> Es gab jedenfalls eine Zeit, in der du mit einer festen Breite arbeiten
> konntest.

Und damit meine ich nicht 7 bit ASCII oder irgendwelche 8 bitigen 
Codepages.

von A. S. (Gast)


Lesenswert?

Nano schrieb:
> Es gab eine Zeit, da galt die Breite von UTF-16 als fix.

Das muss aber eine kurze Zeit gewesen sein, wo es nur die BMP gab.

Abgesehen davon tun genau das heute noch viele. So wie ASCII quasi utf-8 
mit fixer Länge ist, so ist es die BMP für utf-16.

Bei mir werden für die escape-sequenzen halt Kästchen dargestellt.

von mh (Gast)


Lesenswert?

Nano schrieb:
> Nö, mein lieber Jungspund. Es ist bestenfalls nur altes Wissen, denn das
> war nicht immer so, das man für UTF-16 eine variable Länge verwendet, Es
> gab eine Zeit, da galt die Breite von UTF-16 als fix.
> Das hat sich dann wohl lediglich mit aufkommen von UTF-32 und dem Wunsch
> die neuen Zeichen auch unterzubringen geändert.
> Es gab jedenfalls eine Zeit, in der du mit einer festen Breite arbeiten
> konntest.

Das ist schlicht und einfach eine Lüge. UTF-16 war von Anfang an als 
Kodierung mit variabler Länge geplant.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Nano schrieb:
> Nö, mein lieber Jungspund. Es ist bestenfalls nur altes Wissen, denn das
> war nicht immer so, das man für UTF-16 eine variable Länge verwendet, Es
> gab eine Zeit, da galt die Breite von UTF-16 als fix.

Du meinst UCS-2. Das wurde bis Windows NT 4.0 von 1996 verwendet. Schon
in Windows 2000 (NT 5.0) wurde auf UTF-16 (d.h. auf variable Länge)
umgestellt. Ich vermute, dass das Windows des TE eins aus dem aktuellen
Jahrtausend ist, so dass wir uns mit ihm nicht über UCS-2 unterhalten
müssen.

: Bearbeitet durch Moderator
von Bernd K. (prof7bit)


Lesenswert?

Thomas M. schrieb:
> Den Zeichensatz den Windows halt hat

Ganz toll. Die Chinesen haben mir letzte Woche Quelltext zukommen lassen 
für einen Displaytreiber, darin enthalten war unter anderem ein Array 
für einen chinesischen Font und die ID jedes Datensatzes waren 
chinesische "Buchstaben" in Stringliteralen in irgendeiner Kodierung die 
man in China oder sonstwo "halt hat". Fuck den Scheiß! Mein Compiler 
hats natürlich nicht geschluckt weil die Strings angeblich zu lang waren 
und zu sehen waren nur Rechtecke und Fragezeichen und anderer 
Zeichenmüll und woher soll der Compiler auch wissen was der Ersteller 
zufällig "halt hatte" an dem einen Tag bei Vollmond und in welcher 
chinesischen Provinz das war? Und das große Rätselraten (Simplified? 
Traditional? Big5? GB18030? GBK? Big5-HKSCS?) und Rumprobieren war 
angesagt um den Scheiß erstmal irgendwie nach UTF8 konvertiert zu 
bekommen.

Weil mal wieder keiner über den eigenen Tellerrand geschaut hat.

Man sollte meinen jemand der die Font-Bitmaps für LCD-Treiber macht hat 
schonmal irgendwann in seinem Leben mal was von Zeichenkodierungen 
gehört hat und daß Leute auf der anderen Seite des Globus vielleicht 
eine andere haben und daß man wenn man schon kein UTF8 nimmt wie normale 
Leute sondern das Windows-irgendwas-haumichblau das "man halt hat" man 
wenigstens dazuschreibt welche von den zwölfunddreißig verschiedenen 
Windows-Kodierungen die es gibt auf der Welt das sein soll.

Oder man nimmt UTF wie jeder andere normale Mensch seit dem letzten 
Jahrtausend.

Und wenn ich dann lese "Den Zeichensatz den Windows halt hat" dann geht 
mir echt der Hut hoch. Sorry, aber echt jetzt. Sowas von.

: Bearbeitet durch User
von Thomas M. (Gast)


Lesenswert?

Entschuldigung ihr Nichtskönner. Ein richtiger Experte muss doch wohl 
wissen was gemeint ist wenn da steht dass ein Fehler kommt. Kann ich 
doch nichts dafür wenn ihr nicht mal halb so viel Ahnung habt wie ihr 
behauptet.

Scheiß C. Bei Pascal gibt es den ganzen sinnlosen Scheiß nicht und meine 
Freunde hätten mir bei Pascal sofort sagen können wo der Fehler liegt. 
Pascal ist nämlich viel besser als C und Pascal-Programmierer sind viel 
besser als ihr C Leute.

von Es ist zum verzweifeln (Gast)


Lesenswert?

Wir hätten bei 7 Bit Ascii bleiben sollen.

Vor 20 noch kamen wir noch mit den 7 Bit aus. Dateinamen, Benutzernamen, 
Passwörter... alles mit ae, oe, ue. Html-Seiten mit &auml; und 
chinesische Domains hiessen 314159.cn . Copyright Zeichen brachten wir 
nicht. Copyright hatten wir komplett ignoriert.

Chinesische Zeichen funktionierten nur in paar multilingualen 
Programmen. Der ascii transfer type lieferte meist Unfug. Das war halt 
so, hat sich niemand drüber aufgeregt.

Unicode war ein Fehler. In Summe hat Unicode mehr neue Probleme 
verursacht, als gelöst.

von Bernd K. (prof7bit)


Lesenswert?

Es ist zum verzweifeln schrieb:
> Unicode war ein Fehler. In Summe hat Unicode mehr neue Probleme
> verursacht, als gelöst.

Nein, Unicode löst all diese Probleme. Eine Kodierung für die ganze Welt 
und alles funktioniert überall.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> Scheiß C. Bei Pascal gibt es den ganzen sinnlosen Scheiß nicht

Du irrst Dich. Natürlich gibt es Zeichencodierungen auch bei Pascal, und 
sie funktionieren dort exakt genauso. Sie sind nämlich von der 
Programmiersprache vollkommen unabhängig; das gleiche Problem hättest Du 
auch bei Assembler, Fortran, Cobol, Java oder was auch immer.

von Es ist zum verzweifeln (Gast)


Lesenswert?

> Nein, Unicode löst all diese Probleme

Ach, Xerox hatte schon 1982 behauptet, die hätten alle Probleme gelöst.

https://www.youtube.com/watch?v=ODZBL80JPqw

Wir hätten uns auch den ganzen Aufwand sparen können, wenn die ganze 
Welt schon 1982 die Xerox Kodierung übernommen hätte.

Software-Entwickler sind halt Leute die grundsätzlich Alles anders 
machen, als der Rest der Welt. Wir können nicht eine gemeinsame Lösung 
in der ganzen Welt durchsetzen. Wir können uns nicht mal mit der 
Abteilung im Büro nebenan auf eine gemeinsame Lösung einigen.

von Bernd K. (prof7bit)


Lesenswert?

Es ist zum verzweifeln schrieb:
>> Nein, Unicode löst all diese Probleme
>
> Ach, Xerox hatte schon 1982 behauptet, die hätten alle Probleme gelöst.
> Wir hätten uns auch den ganzen Aufwand sparen können, wenn die ganze
> Welt schon 1982 die Xerox Kodierung übernommen hätte.

Xerox-Leute waren an der Entstehung von Unicode maßgeblich beteiligt, 
basierend auf deren vorherigen Ideen und Erfahrungen mit der 
Xerox-Kodierung.

Es ist nicht klar was Du eigentlich für eine Kritik vorbringen willst an 
Unicode. In der Praxis funktioniert es, es wird von jedem OS und jeder 
nennenswerten Software, jeder Library, jedem Framework, jeder 
Programmiersprache unterstützt und es löst all die unsäglichen Probleme 
aus der dunklen Zeit der großen Kodierungswirren, endlich kann man den 
Kopf komplett frei haben von diesem riesigen babylonischen 
Kodierungsmisthaufen den man damals hatte bevor sich überall Unicode und 
UTF durchgesetzt hat und kann sich endlich voll auf die eigentliche 
Anwendung konzentrieren. Wünscht Du Dir etwa diese Zeit mit all diesem 
nervtötenden Krampf und den kaputten Umlauten und Sonderzeichen zurück, 
dieser elende Krampf der so viel Zeit und Nerven unnütz vernichtet hat?

Wenn mir heute im Jahr 2019 noch jemand einen Quelltext unterjubeln will 
mit Sonderzeichen in irgendeinem obskuren Windows-hat-man-halt Format 
kodiert dann möchte ich dem ein herzliches "fuck you!" zurufen! Und dann 
wirds umgewandelt nach UTF-8 damits kompatibel wird mit der übrigen EDV 
in diesem Sektor der Milchstraße! So siehts aus!

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bernd K. schrieb:
> in in irgendeinem obskuren Windows-hat-man-halt Format kodiert

Was übrigens Windows nicht vorzuwerfen ist - das versteht schon seit 
längerem UTF-8, selbst Notepad.exe versteht das. Und die 
Entwicklungssysteme von MS (Visual Studio & Co.) tun das auch schon seit 
geraumer Zeit.

Der 8-Bit-Codepage-Kram stammt aus der fossilen Zeit vor Windows NT 
(das bereits 1993 wusste, was Unicode ist, wenn auch damals noch mit 
festen 16-Bit-Zeichen).

von Dirk B. (dirkb2)


Lesenswert?

Es ist zum verzweifeln schrieb:
> Wir hätten bei 7 Bit Ascii bleiben sollen.

Und bei 8.3 Dateinamen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Es ist zum verzweifeln schrieb:
1
> Wir hätten bei 7 Bit Ascii bleiben sollen.
2
       ^
3
      Ja!

von Es ist zum verzweifeln (Gast)


Lesenswert?

>Wenn mir heute im Jahr 2019 noch jemand einen Quelltext unterjubeln will

Es gibt halt tausende von Detailproblemen.

Nur so als Beispiel - Wir haben uns immer noch nicht geeinigt, wie wir 
"int main(int argc, char *argv[])" auf "int main(int argc, char16_t 
*argv[])" umstellen. Inzwischen hat sich heraus gestellt, wir sollten 
char32_t statt char16_t benutzen.

Dir jubelt jemand einen Quelltext für ein grep Utility unter, der immer 
noch "int main(int argc, char *argv[])" benutzt. Du willst aber mit 
diesem Tool nach Copyright-Zeichen und Smilies in UTF-8 Dateien suchen.

Konkrete Frage, wie löst du dieses Detailproblem? Ganz egal, welchen 
Vorschlag du machst - irgend jemand wird dir sagen, dein Vorschlag sei 
idiotisch, das müsse man anders anpacken.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Es ist zum verzweifeln schrieb:
> Nur so als Beispiel - Wir haben uns immer noch nicht geeinigt, wie wir
> "int main(int argc, char *argv[])" auf "int main(int argc, char16_t
> *argv[])" umstellen. Inzwischen hat sich heraus gestellt, wir sollten
> char32_t statt char16_t benutzen.

Wir belassen es bei char, verwenden aber UTF-8 als Zeichenkodierung für
die Ein-/Ausgabe von Texten.

> Dir jubelt jemand einen Quelltext für ein grep Utility unter, der immer
> noch "int main(int argc, char *argv[])" benutzt. Du willst aber mit
> diesem Tool nach Copyright-Zeichen und Smilies in UTF-8 Dateien suchen.

Warum nicht? Das funktioniert problemlos.

> Konkrete Frage, wie löst du dieses Detailproblem?

Wie ich oben schon schrieb:

- für Ein-/Ausgabe UTF-8 (spart auch etwas Platz auf der Festplatte)

- intern optional UTF-32 (wenn man Strings häufig zeichenweise
  verarbeiten muss)

von guest (Gast)


Lesenswert?

Yalu X. schrieb:
> 2. Windows: Wann wird welche Zeichenkodierung verwendet? Es gibt da
>    bspw. die Loseblattsammlung namens MSDN, wo du dich durchwühlen
>    kannst

MSDN nennt sich neuerdings "Microsoft Docs": https://docs.microsoft.com/

Yalu X. schrieb:
> Rufus Τ. F. schrieb:
>> Das Auswählen der Codepage kann einerseits in der Kommandozeile
>> erfolgen:
>>
>> mode con cp select=1252
>
> Kann man damit auch UTF-8 einstellen (passender Font natürlich
> vorausgesetzt)?

Ja "mode con cp select=65001".

von Nano (Gast)


Lesenswert?

Yalu X. schrieb:
> Nano schrieb:
>> Nö, mein lieber Jungspund. Es ist bestenfalls nur altes Wissen, denn das
>> war nicht immer so, das man für UTF-16 eine variable Länge verwendet, Es
>> gab eine Zeit, da galt die Breite von UTF-16 als fix.
>
> Du meinst UCS-2. Das wurde bis Windows NT 4.0 von 1996 verwendet.

Okay, UCS-2 war früher halt als Unicode bekannt und wurde so bezeichnet 
und unter dieser Bezeichnung auch überall geführt.

"The original idea was to replace the typical 256-character encodings 
requiring 1 byte per character with an encoding using 216 = 65,536 
values requiring 2 bytes per character. Two groups worked on this in 
parallel, the IEEE and the Unicode Consortium, the latter representing 
mostly manufacturers of computing equipment. The two groups attempted to 
synchronize their character assignments so that the developing encodings 
would be mutually compatible. The early 2-byte encoding was usually 
called "Unicode", but is now called "UCS-2".
https://en.wikipedia.org/wiki/UTF-16#History

Die Bezeichnung UCS-2 ist neuer als Unicode.
Und das damalige Unicode war so gesehen eben 16 bittig, weil man 
ursprünglich davon ausging, das einem die 16 bit ausreichen würden.

Insofern ja, nach heutiger Terminologie meine ich dann UCS-2 wenn ich 
von einem 2 Byte großen Unicode mit fester breite spreche.

von Nano (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Thomas M. schrieb:
>> Scheiß C. Bei Pascal gibt es den ganzen sinnlosen Scheiß nicht
>
> Du irrst Dich. Natürlich gibt es Zeichencodierungen auch bei Pascal, und
> sie funktionieren dort exakt genauso. Sie sind nämlich von der
> Programmiersprache vollkommen unabhängig; das gleiche Problem hättest Du
> auch bei Assembler, Fortran, Cobol, Java oder was auch immer.

Bei D sind ALLE Strings in Unicode, da ist es fester Bestandteil der 
Sprache.

"Unicode has fixed most of those problems and is supported on every 
modern machine. D learns from the mistakes of older languages, as such 
all strings in D are Unicode strings, whereas strings in languages such 
as C and C++ are just arrays of bytes.

In D, string, wstring, and dstring are UTF-8, UTF-16, and UTF-32 encoded 
strings respectively. Their character types are char, wchar, and dchar."
https://tour.dlang.org/tour/en/gems/unicode


Bei Rust ist es ähnlich, das achtet darauf, dass man einen String nicht 
indexiert, bzw. wirft einen Compilererror wenn man es doch tut.
Es liefert dafür aber entsprechende Möglichkeiten um auf einzelne 
Zeichen zuzugreifen:

https://doc.rust-lang.org/book/ch08-02-strings.html


Lösung des Problems.
Verwendet eine moderne Programmiersprache wie D oder Rust, dann müsst 
ihr euch auch nicht mit so etwas rumärgern.

von test (Gast)


Lesenswert?

Nano schrieb:
> Lösung des Problems.
> Verwendet eine moderne Programmiersprache wie D oder Rust, dann müsst
> ihr euch auch nicht mit so etwas rumärgern.

Das aktuelle Programmiersprachen intern in Unicode arbeiten ist 
heutzutage nix besonderes mehr.

Das Problem ist das viele Nutzer die Codierung ihrer Quelltexte nicht 
explizit definieren. Und das sie nicht konsequent alle Ein-/Ausgaben 
explizit konvertieren (wird halt genommen was zufällig da ist, wird 
schon passen).
Ferner gibts dann noch Leute die ihre Daten (egal ob Strings oder 
Binärdaten) in irgendwelche Arrays vom Type Char packen, weil das hat 
man ja schon immer so gemacht.

von Nano (Gast)


Lesenswert?

test schrieb:
> Nano schrieb:
>> Lösung des Problems.
>> Verwendet eine moderne Programmiersprache wie D oder Rust, dann müsst
>> ihr euch auch nicht mit so etwas rumärgern.
>
> Das aktuelle Programmiersprachen intern in Unicode arbeiten ist
> heutzutage nix besonderes mehr.

Die Altlasten sind es.

Kannst ja mal strchr() auf ein chinesisches Zeichen in UTF-8 Kodierung 
anwenden, dann fliegt dir das um die Ohren.

Es wird praktisch in C und C++ mit externen Libraries oder einer 
Erweiterung der Standardlibaries versucht, das Problem irgendwie in den 
Griff zu kriegen, aber letzten Endes ist es ein Wildwuchs.

> Das Problem ist das viele Nutzer die Codierung ihrer Quelltexte nicht
> explizit definieren. Und das sie nicht konsequent alle Ein-/Ausgaben
> explizit konvertieren (wird halt genommen was zufällig da ist, wird
> schon passen).

Ja, der menschliche Faktor kommt noch dazu. Da sind die alten Sprachen 
keine Hilfe.

von Nano (Gast)


Lesenswert?

Es fängt vor allem auch damit an, welche Lib man denn wählen soll wenn 
man mit Unicode Zeichen arbeiten möchte.

Das was C standardmäßig liefert und so eigene Umbauten wie hier 
empfohlen:
https://www.cprogramming.com/tutorial/unicode.html

Oder doch lieber irgendwelche Bibliotheken, die eine Unicode 
Unterstützung eingebaut haben, wie bspw. GTK oder Qt.

Oder rauf Unicodezeichen spezialisierte Libs, wie bspw. ICU4C.
http://site.icu-project.org/

Man hat praktisch die Qual der Wahl, die bei modernen Sprachen wie D und 
Rust entfällt weil es dort zum Sprachumfang gehört und man nicht mit dem 
alten Zeugs sich herumärgern muss.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Nano schrieb:
> Verwendet eine moderne Programmiersprache wie D oder Rust, dann müsst
> ihr euch auch nicht mit so etwas rumärgern.

Die Programmiersprache ist erst die halbe Miete. Die Entwicklungs- und
die Laufzeitumgebung müssen ebenfalls konsequent Unicode unterstützen,
damit hinterher alles ohne zusätzlichen Programmieraufwand glatt läuft.

Dies ist bei Windows derzeit (noch) nicht gegeben, da es bspw. immer
noch Texteditoren gibt, die den Programmquelltext defaultmäßig in einer
anderen Kodierung als UTF-8 speichern. Wird das D-Programm dann aus
einer "Eingabeaufforderung" gestartet, stehen die Chancen groß, dass
diese ebenfalls nicht auf UTF-8 eingestellt ist und somit Ein- und
Ausgaben verstümmelt werden. Des Weiteren gibt es Unterschiede bei den
Dateisystemen: Während NTFS bereits Unicode für Dateinamen verwendet,
ist dies bei den FAT-Dateisystemen nicht der Fall.

Das alles kann man zwar beim Schreiben eines Programms bis zu einem
gewissen Grad berücksichtigen, indem man Texte und Namen jeweils passend
konvertiert. Aber dazu muss sich der Programmierer erst einmal des
Problems bewusst sein und sich überlegen, wie er es mit den Mitteln, die
D oder eine beliebige andere Programmiersprache bereitstellt, am besten
löst.

Wie ich schon weiter oben geschrieben habe, gestaltet sich die Sache mit
Python 3 in einer Linux-Umgebung besonders einfach. Tatsächlich sieht
ein Python-3-Programm mit Unicode-Stringverarbeitung und Ein-/ Ausgabe
kaum anders aus als eines in Python 2 mit 8-Bit-Zeichensatz. Da Strings
intern in UTF-32 gespeichert werden, gibt es auch keine Überraschungen
bei der Indizierung und Längenbestimmung.

Sobald man aber dasselbe Python-3-Programm unter Windows nutzen möchte,
mal in einer "Eingabeaufforderung" und mal in einer GUI-Umgebung, wird
man mit hoher Wahrscheinlichkeit auf Probleme stoßen. Hat man aber die
Problematik erst einmal gut genug verstanden, um sie in Python zu lösen,
schafft man dasselbe mit etwas RTFM auch in anderen Programmiersprachen
wie bspw. C.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Während NTFS bereits Unicode für Dateinamen verwendet,
> ist dies bei den FAT-Dateisystemen nicht der Fall.

Da kaum noch jemand die 8.3-Namen verwendet, ist das nicht relevant.

Die FAT-Erweiterung für "lange Dateinamen"* namens VFAT nutzt UTF-16.

> Wird das D-Programm dann aus
> einer "Eingabeaufforderung" gestartet, stehen die Chancen groß, dass
> diese ebenfalls nicht auf UTF-8 eingestellt ist

Darum könnte sich der Startupcode kümmern, indem er per API-Aufruf die 
Konsole auf UTF-8 umstellt.


*) ich neige dazu, das als die Einführung von Dateinamen anstelle von 
Kürzeln zu bezeichnen; DOS hatte einfach keine Dateinamen ...

: Bearbeitet durch User
von Ralf D. (doeblitz)


Lesenswert?

Rufus Τ. F. schrieb:
> Yalu X. schrieb:
>> Während NTFS bereits Unicode für Dateinamen verwendet,
>> ist dies bei den FAT-Dateisystemen nicht der Fall.
>
> Da kaum noch jemand die 8.3-Namen verwendet, ist das nicht relevant.
>
> Die FAT-Erweiterung für "lange Dateinamen"* namens VFAT nutzt UTF-16.

Damit hast du unter Windows dann deine Ruhe. Aber sobald du in 
heterogenen Umgebungen arbeitest lernst du die Freuden der 
unterschiedlichen Normalformen kennen. Und natürlich müssen Entwickler 
diese Normalformen nicht zwingend verwenden, theoretisch kann man in den 
Namen auch partially composed oder eine Mischung der Normalformen 
verwenden.

Es macht wirklich Spaß, wenn man parallel mehrere Dateien nicht nur 
optisch sondern auch semantisch identischen Namen hat und dann gezielt 
eine davon durch Eingabe eines Namens auswählen möchte. Hüalp.

Zum Kennenlernen einiger diesbezüglicher Probleme kann ich nur die 
Lektüre des Unicode-Kapitels im Camel Book ("Programming Perl", OReilly) 
empfehlen. Unicode verursacht zwar keine Probleme, aber es zeigt 
verdammt viele auf, die man als Westeuropäer früher gerne ignoriert hat.

Beitrag #5705166 wurde vom Autor gelöscht.
Beitrag #5705179 wurde vom Autor gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.