Was machen Programmier-Anfänger mit ihren Fragen?

Smalltalk
ViNic

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von ViNic » 17.12.2018 10:44:47

Also ich würde die Benennung der Variablen bemängeln, die Einrückungen im Code und das Code anscheinend doppelt vorhanden ist.

Ist aber nur meine Meinung.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 17.12.2018 10:45:16

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 10:19:37
Ich wollte die neue Funktion gleich mitbringen, aber ich habe noch Probleme mit dem Vergleich meiner beiden Zahlen-Sequenzen. Wo kann ich eigentlich herausfinden, ob Zahlen immer Einzelbytes sind bzw. ob man die dann auch ganz einfach mit ">" "<" vergleichen kann?
Du koenntest auch einfach mit strtol(3) vergleichen, dann bekommst du auch gleich das Suchen des Zahlenendes geschenkt (bloss wuerde das sowas wie ``1234e-56'' als eine Zahl interpraetieren ...). Die Ziffern sind alle Teil von US-ASCII, insofern kannst du die auch direkt vergleichen, aber ...
Was ich noch gerne fragen wollte: Was genau macht Code wie den in meinen obigen Funktionen eigentlich unleserlich? Ist das dahinterstehende Konzept nicht klar genug oder schlecht, oder ist der Code von der Syntax her nicht strukturiert genug, oder was genau ist es?
... genau das macht Code unleserlich, Low-Level-Code, der Bytes vergleicht. Der Grund ist, dass er nur schwer erkennen laesst, was *inhaltlich* gemacht wird. Wenn du also nicht strtol(3) verwendest, dann schreibe dir selber eine strnumcmp() oder so, die zwei Strings entgegen nimmt und die in ihnen enthaltenen Zahlen vergleicht.

Code wird beispielsweise lesbarer, wenn jede Funktion nur auf einem Abstraktionslevel arbeitet. Die eine Funtion arbeitet auf Bytes, die darueber auf Chunks von Strings, die darueber auf ganzen Strings. Sowas hilft.

Ansonsten sei auf den Telefontest verwiesen. (Siehe dazu auch: viewtopic.php?f=34&t=165425 )

Wenn du ein Buch lesen willst, dann ist meine beste Empfehlung: ``The Practice of Programming'' von Kernighan und Pike.
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 17.12.2018 17:10:04

Danke für eure Anregungen! :THX:
Meillo hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 10:45:16
Du koenntest auch einfach mit strtol(3) vergleichen[…]
Dann kann die Zahlenfolge aber nicht beliebig lang sein, oder?
Meillo hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 10:45:16
Die Ziffern sind alle Teil von US-ASCII, insofern kannst du die auch direkt vergleichen […]
Also auch bei irgendeinem anderen Encoding und sogar in der Form (a == '0') (nach geeignetem setlocale() natürlich)? Wenn ja, ist das toll, so habe ich die neue Funktion auch einfach mal verfasst. Allerdings habe ich dann das mit den Encodings noch nicht ganz verstanden...
Vielen Dank übrigens für die Buch-Empfehlung, hört sich sehr interessant an!
eggy hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 10:44:22
c) Es fehlen Headerfiles. Sie ermöglichen ein schnelles Überfliegen "was ist in der Datei, welche Funktionen gibt es", man kann sich gedanklich auf den Code vorbereiten, hat praktisch eine "Karte", wo es langgehen wird, wenn man den restlichen Code liest.
Ja, bei einem "ganzen" Programm mache ich auch immer eine schöne Header-Datei, in der ich auch die globalen Variablen kurz erkläre (habe ich mir von Linus Torvalds uemacs abgeschaut...). Aber ich habe jetzt mal alle Funktionen ganz oben separat deklariert.

Ich habe versucht, alle eure Kommentare zu berücksichtigen und den von @meillo vorgeschlagenen Ablauf so gut ich konnte einzuhalten:
NoPaste-Eintrag40535
Zeile 93 ist vielleicht noch etwas kompliziert...
Was dort passiert:
--------------
wenn len1 == 0 und i == 0, dann ist s1 größer, deshalb len2-len1
wenn len1 == 0 und i > 0, dann ist s2 größer, deshalb len1-len2
wenn len2 == 0 und i == 0, dann ist s2 größer, deshalb len2-len1
wenn len2 == 0 und i > 0, dann ist s1 größer, deshalb len1-len2
-------------
Vielleicht sollte man sowas im Code doch weiter auseinanderpflücken? Allerdings sieht es so als ein if wenn man es mal durchschaut hat übersichtlicher aus...

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von eggy » 17.12.2018 17:20:44

Code: Alles auswählen

int
main(int argc, char *argv[])
{
Der Typ des Rückgabewerts gehört in C und vielen anderen Sprachen mit zur Signatur. Daher sollte er mit dem Rest der Signatur auf einer Zeile sein.

Code: Alles auswählen

int main(int argc, char *argv[]) {
Dass Du die Klammern auf der nächsten Zeile setzt, ist hingegen reine Geschmackssache. Ich finde öffnende Klammer auf neuen Zeilen absolut fürchterlich, für mich gehören die ans Ende der Zeile. Macht es aus meiner Sicht dann auch wieder nen ganzes Stück schneller lesbar. Aber wie gesagt, der Teil ist Geschmackssache.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 17.12.2018 21:48:15

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 17:10:04
Meillo hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 10:45:16
Du koenntest auch einfach mit strtol(3) vergleichen[…]
Dann kann die Zahlenfolge aber nicht beliebig lang sein, oder?
Korrekt erfasst. Daran habe ich nicht gedacht. ;-)
Meillo hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 10:45:16
Die Ziffern sind alle Teil von US-ASCII, insofern kannst du die auch direkt vergleichen […]
Also auch bei irgendeinem anderen Encoding und sogar in der Form (a == '0') (nach geeignetem setlocale() natürlich)?
AFAIK sind in jedem bekannten Locale die Ziffern 0-9 aufsteigend direkt hintereinander. Du kannst zwei Ziffern also anhand ihrer Character-Values vergleichen und bekommst die nummerisch korrekten Ergebnisse.

Bloss mit sowas wie UTF-16 kenne ich mich nicht aus.
Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 17.12.2018 22:04:12

eggy hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 17:20:44

Code: Alles auswählen

int
main(int argc, char *argv[])
{
Der Typ des Rückgabewerts gehört in C und vielen anderen Sprachen mit zur Signatur. Daher sollte er mit dem Rest der Signatur auf einer Zeile sein.

Code: Alles auswählen

int main(int argc, char *argv[]) {
Dass Du die Klammern auf der nächsten Zeile setzt, ist hingegen reine Geschmackssache. Ich finde öffnende Klammer auf neuen Zeilen absolut fürchterlich, für mich gehören die ans Ende der Zeile. Macht es aus meiner Sicht dann auch wieder nen ganzes Stück schneller lesbar. Aber wie gesagt, der Teil ist Geschmackssache.
Ersteres ist aber ein durchaus verbreiteter Stil in C.

K&R schreiben die oeffnende geschweifte Klammer bei Funktionen (nur da!) auch auch in eine neue Zeile. Der vi beruecksichtigt das auch, denn da kann man mit [[ und ]] dann von Funktion zu Funktion springen. ;-)

Historisch gesehen gab es in Pre-ANSI-C keine Rueckgabetypangaben und die Argumenttypen wurden *zwischen* die Funktionssignatur und die oeffnende geschweifte Klammer geschrieben. Darum ist die oeffnende geschweifte Klammer in einer extra Zeile.

Den Rueckgabetyp in eine extra Zeile zu schreiben hat den schoenen Vorteil, dass man dann mit der RegExp /^foo(/ direkt zur Definition der Funktion foo springen kann. K&R machen das so zwar nicht, ich mache es aber gerne so. Ausserdem ist es hilfreich, wenn man komplexe Typen zurueckliefert und viele Argumente mit komplexen Typen hat, weil man sich dann oft Umbrueche auf 80 Columns spart. (Und man muss den Funtionsnamen nicht suchen, wenn man ohne Syntax-Highlighting arbeitet.)

Wie du schreibst, ist manches Geschmackssache. Fuer manches gibt es Begruendungen die im einen oder anderen Fall relevant sind. Wie man es auch macht, man sollte begruenden koennen, warum man es so macht und nicht anders. (Eine Begruendung waere, dass die Programmiercommunity in der man sich bewegt es so macht und man sich ihr anpasst.)
Use ed once in a while!

tobo
Beiträge: 1989
Registriert: 10.12.2008 10:51:41

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von tobo » 17.12.2018 22:07:55

eggy hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 17:20:44
Der Typ des Rückgabewerts gehört in C und vielen anderen Sprachen mit zur Signatur. Daher sollte er mit dem Rest der Signatur auf einer Zeile sein.
Das ist genauso Geschmacksache. Zwei z.B., die das anders sehen:
https://www.gnu.org/prep/standards/standards.html
https://suckless.org/coding_style/

PS: Diese Anzeige, dass da inzwischen ein weiterer Beitrag war, scheint aber auch nicht immer zu funktionieren!?

Benutzeravatar
novalix
Beiträge: 1909
Registriert: 05.10.2005 12:32:57
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: elberfeld

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von novalix » 18.12.2018 00:57:29

(sorry für OT)
tobo hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 22:07:55
PS: Diese Anzeige, dass da inzwischen ein weiterer Beitrag war, scheint aber auch nicht immer zu funktionieren!?
Das scheint immer dann nicht zu funktionieren, wenn man den "Vorschau"-Modus benutzt hat.
Das Wem, Wieviel, Wann, Wozu und Wie zu bestimmen ist aber nicht jedermannns Sache und ist nicht leicht.
Darum ist das Richtige selten, lobenswert und schön.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 18.12.2018 10:00:23

Meillo hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 21:48:15
AFAIK sind in jedem bekannten Locale die Ziffern 0-9 aufsteigend direkt hintereinander. Du kannst zwei Ziffern also anhand ihrer Character-Values vergleichen und bekommst die nummerisch korrekten Ergebnisse.
Ok, aber sind das auch immer Singlebytes? Sowas muss doch irgendwo stehen. Für Unicode habe ich nun das hier gefunden: https://en.wikipedia.org/wiki/Compariso ... #In_detail . Demnach müsste ich den Loop über die Zahlen doch umschreiben, da doch nicht eine Zahl = ein Byte gilt.

Zum Style:
Ich schreibe bei Funktionen immer Rückgabewert und geschweifte Klammer in eine separate Zeile, da ich es viel übersichtlicher finde. (Ich nutze auch kein syntax highlighting, außer für Kommentare). Gerade, wenn eine Funktion viele Argumente entgegennimmt, ist die Klammer auf der nächsten Zeile sehr gut, da dann Freiraum ist zwischen der Liste der Argumente und den Deklarationen der Variablen. Außerdem möchte ich immer gerne unter 81 Columns bleiben, da das angenehmer ist, wenn man zwei Dateien nebeneinander bearbeitet (tiling window manager / split screen in vim).

@meillo: Als ich gestern nach einem "Blick ins Buch" von "The Practice of Programming" suchte, habe ich u.a. das hier gefunden: https://www.oreilly.com/library/view/th ... /ch01.html . Das Zitat kenne ich sogar, denn "The Elements of Style" von William Strunk (https://en.wikipedia.org/wiki/The_Elements_of_Style) habe ich sogar als Buch bzw. eher Heft. (Eine hübsche neuere Ausgabe, die ich mal in einer Buchhandlung gefunden habe, da ich dort immer auch nach versteckten kleinen Büchlein schaue. Die Buchhändlerin wusste gar nicht, dass sie das hatte, und hat den Preis nicht mehr im Computer gefunden, deshalb habe ich es sogar geschenkt bekommen. :D )

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 18.12.2018 10:21:10

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 10:00:23
Meillo hat geschrieben: ↑ zum Beitrag ↑
17.12.2018 21:48:15
AFAIK sind in jedem bekannten Locale die Ziffern 0-9 aufsteigend direkt hintereinander. Du kannst zwei Ziffern also anhand ihrer Character-Values vergleichen und bekommst die nummerisch korrekten Ergebnisse.
Ok, aber sind das auch immer Singlebytes? Sowas muss doch irgendwo stehen. Für Unicode habe ich nun das hier gefunden: https://en.wikipedia.org/wiki/Compariso ... #In_detail . Demnach müsste ich den Loop über die Zahlen doch umschreiben, da doch nicht eine Zahl = ein Byte gilt.
In UTF-16 ist es natuerlich kein Single-Byte, weil dort alle Zeichen zwei Bytes haben. ;-) (Aber mit solchen Sackgassentechnologien beschaeftige ich mich nicht :-P darum kann ich dazu nichts sagen.)

@meillo: Als ich gestern nach einem "Blick ins Buch" von "The Practice of Programming" suchte, habe ich u.a. das hier gefunden: https://www.oreilly.com/library/view/th ... /ch01.html . Das Zitat kenne ich sogar, denn "The Elements of Style" von William Strunk (https://en.wikipedia.org/wiki/The_Elements_of_Style)
``The Elements of Style'' wird in mehreren der Computerbuecher von den Autoren um Kernighan erwaehnt. Die Denkweisen passen auch gut zusammen (``Omit needless words!'' ;-) ). Sozusagen der Vorlaeufer von ``The Practice of Programming'' (1999) ist ``The Elements of Programming Style'' (1974) von Kernighan und Plauger. Das ist nicht nur vom Titel angelehnt. Allerdings kommt das noch aus der Fortran-Zeit. Man braucht schon ein bisschen historischen Background, wenn man das mit Vergnuegen lesen will. Das Buch von 1999 ist sozusagen die moderne(re) Verarbeitung des gleichen Themas.
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 18.12.2018 13:22:54

Meillo hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 10:21:10
Aber mit solchen Sackgassentechnologien beschaeftige ich mich nicht :-P
Möchtest Du damit andeuten, dass ich Multi-Byte-Zahlen einfach erstmal in die "Limitations"-File* schreiben soll? Weil ASCII, UTF-8, dieses Latin1 und viele andere scheinen ja die Zahlen als Single-Bytes zu implementieren.
Manchmal ist es bei so Sondersachen etwas schwierig, finde ich, mit der Entscheidung, ob man sie umsetzt oder nicht. Sie dauern am längsten beim Programmieren und man läuft Gefahr, dass einer der folgenden Fälle eintritt:
1) man gibt auf (kann mir eher nicht passieren)
2) der ganze Code wird schlecht, hat aber dafür Unterstützung für 0,001% der Anwendungsfälle
3) es hat kein einziger der künftigen User gebraucht

*In der steht übrigens noch nichts, denn mein file manager kann mit Pfadlängen > PATH_MAX umgehen, das habe ich getestet. (Einzig bei symbolischen Links bin ich mir noch nicht ganz sicher...)

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 18.12.2018 14:11:36

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 13:22:54
Meillo hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 10:21:10
Aber mit solchen Sackgassentechnologien beschaeftige ich mich nicht :-P
Möchtest Du damit andeuten, dass ich Multi-Byte-Zahlen einfach erstmal in die "Limitations"-File* schreiben soll? Weil ASCII, UTF-8, dieses Latin1 und viele andere scheinen ja die Zahlen als Single-Bytes zu implementieren.
Ich bin der Meinung, dass alle Encodings ausser UTF-8 Sackgassen sind. Sie haben mehr Nachteile als Vorteile gegenueber UTF-8. Gerade UTF-16 ist einfach nur schrecklich: Man hat Byte-Order-Probleme, die es bei UTF-8 nicht gibt. Man kann zwar ein paar Zeichen ein bisschen effizienter kodieren als mit UTF-8, die fast haeufigsten Zeichen aber ineffizienter. Reine CJK-Texte sind in UTF-8 zwar groesser als in UTF-16, aber das umfasst nur ein Drittel weniger Platzverbrauch, der nur bei einem Viertel aller Zeichen vorhanden ist. UTF-8 kann auch mehr Zeichen kodieren, als UTF-16. Derzeit wird das nicht genutzt, aber es existiert Raum zur Erweiterung (ohne dass man Sonderfaelle einfuehren muesste). UTF-8 hat eine viel bessere Robustheit, beim Uebertragungsfehlern.

In Summe: UTF-16 schafft durch seine Existenz mehr Probleme als es loest. Es waere besser gewesen, es haette es nie gegeben ... dann haette man es gleich richtig machen koennen, naemlich mit UTF-8.


... nun gut, UTF-9 ist das einzige andere Encoding, das ich noch gelten lasse: https://tools.ietf.org/html/rfc4042 ;-)



Zum Thema: Was du in deinem speziellen Fall machen sollst, kann ich nicht sagen. Direktes Rumwerkeln mit Bytes wird dir immer Inkompatibilitaeten mit irgendwelchen Encodings einhandeln. Da musst du selber entscheiden was dir wichtiger ist. Ich fuer mich wuerde sagen: Vergiss alle Zeitperformance und nutze Bibliotheksfunktionen, die dieses ganze Encoding-Zeugs fuer dich uebernehmen. Wenn das dann alles korrekt funktioniert, dann baust du es in deine Anwendung ein und dann erst schaust du mal, ob es wirklich zu langsam ist.

... andererseits lernst du auf dem Weg sicher nicht so viel ueber Encodings. ;-)

Btw: https://ulm.ccc.de/ChaosSeminar/2016/10 ... oding-font
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 18.12.2018 16:33:44

Meillo hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 14:11:36
Vergiss alle Zeitperformance […]
An die habe ich jetzt auch wirklich gerade nicht mehr gedacht!

Aber bevor ich doch vielleicht wieder mit "mblen()" und "strcoll()" die Zahlen vergleiche: Was ich noch gerne fragen wollte, ist, wie man den Wert eines Bytes eines integers (oder einer anderen größere Dateneinheit) bekommt. Wenn ich das richtig verstehe, so:

Code: Alles auswählen

char byte[4];
int i;

byte[3] = i & 0xFF;
byte[2] = (i >> 8) & 0xFF;
byte[1] = (i >> 16) & 0xFF;
byte[0] = (i >> 24) & 0xFF;
Das "&" deshalb, weil 0xFF = 11111111 ist. Dann werden mit dem "&" alle Bits, die 1 sind, als 1 übernommen und alle anderen als "0", da nur 1 und 1 gleich 1 ist, aber 0 und 1 gleich 0.
Oder geht auch:

Code: Alles auswählen

char byte[4];
int i;

byte[0] = (i << 24) & 0xFF;
byte[1] = (i << 16) & 0xFF;
byte[2] = (i << 8) & 0xFF;
byte[3] = i & 0xFF;
?
i wird ja nie bleibend verändert, oder?

Danke übrigens für den Link zu Deinem Vortrag und Deinem Material. Da hast Du Dir ja richtig viel Mühe gemacht! :THX:
Also, ASCII = Charset, Unicode = Charset, aber UTF-8 = Encoding.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 18.12.2018 22:37:16

Ein int kann vier Bytes gross sein, Er kann aber auch nur zwei Bytes gross sein, und wahrscheinlich kann er auch acht Bytes gross sein (das muesste ich aber nochmal nachlesen). Du triffst also eine Annahme, die den Code unportabel macht.

Besser waere es, ``sizeof(int)'' zu verwenden, um die Groesse zu ermitteln.

Zudem hast du Byte-Orders noch nicht bedacht, also Big Endian und Little Endian.
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 18.12.2018 22:45:41

Nein, nein, ich wollte das nicht genau so in meine Funktion einbauen, keine Sorge! Ich hatte mich nur mal prinzipiell dafür interessiert. Der zweite Schnipsel ist übrigens falsch (habe es einfach mal kompiliert und probiert) und müsste heißen:

Code: Alles auswählen

	byte[0] = (i >> 24) & 0xFF;
	byte[1] = (i >> 16) & 0xFF;
	byte[2] = (i >> 8) & 0xFF;
	byte[3] = i & 0xFF;
Ich werde jetzt eben doch wieder mit mblen und strcoll die Zahlen vergleichen. Du hast schon Recht - warum unnötig Inkompatibilitäten in Kauf nehmen...

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 18.12.2018 22:53:50

Aber schau dir das Byte-Order-Zeug ruhig mal an. Dann verstehst du z.B. auch, warum es UTF-16-LE und UTF-16-BE gibt, aber nur ein UTF-8.

Ich finde es gut, dass du diese ganzen Experimente machst. Nur weiter so!
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 18.12.2018 23:14:51

Danke. Leider muss ich spätestens zum 20.12. (also übermorgen) mit dem Experimentieren erstmal praktisch aufhören, da ich Mitte Januar Prüfungen habe (und Anfang April noch einmal...). Nennt sich Abitur oder so. :mrgreen: (Für Leistungskurs Mathematik bin ich ja schonmal bestens gerüstet, da ich nun ja weiß, dass 1+1=1 ist... 8) )
Aber ein Zwischenergebnis können wir ja auf jeden Fall schon einmal festhalten: Als Programmier-Anfänger ist man mit seinen Fragen hier im debianforum auf jeden Fall richtig. Danke! :THX:

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 07.03.2019 10:42:32

Ich muss mal für interessierte Mitleser ein kleines Update machen, auch wenn meine Funktion immer noch nicht fertig ist (ich habe bisher aber schon mindestens 10 Entwürfe angefertigt).
Denn ich glaube, dass mir kürzlich etwas Wesentliches klar geworden ist:

Für den Linux-Kernel sind Dateinamen eine Kette von Bytes, also in C ausgedrückt ein "char"-Array. Deswegen gibt es für Linux-Systeme auch nur Funktionen wie "open()" oder "fopen()", die als Dateinamen einen Pointer zu einem "char"-Array erwarten, nicht etwa einen Pointer zu einem "wchar_t"-Array.
So, aber damit ist auch klar, dass Dateinamen niemals in UTF-16 oder UTF-32 codiert sein können! Denn beide Encodings nutzen Null-Bytes, um überflüssigen Platz in den zwei-/vier-Byte-Einheiten aufzufüllen.
Ihr könnt das sehr schön an einem kleinen Experiment sehen. Man öffne vim und tippe ein "ä" in den Buffer. Anschließend speichere man es unter verschiedenen Encodings in verschiedenen Dateien, also z.B. mit:

Code: Alles auswählen

:w ++enc=utf-8 u8
:w ++enc=utf-16 u16
:w ++enc=utf-32 u32
Anschließend hat man:

Code: Alles auswählen

user@hostname:~$ ll u*
-rw-r--r-- 1 user user 4 Mar  7 10:09 u16
-rw-r--r-- 1 user user 8 Mar  7 10:09 u32
-rw-r--r-- 1 user user 3 Mar  7 10:09 u8
und:

Code: Alles auswählen

user@hostname:~$ hd u16
00000000  00 e4 00 0a                                       |....|
00000004
user@hostname:~$ hd u32
00000000  00 00 00 e4 00 00 00 0a                           |........|
00000008
user@hostname:~$ hd u8
00000000  c3 a4 0a                                          |...|
00000003
("0a" ist das newline-Zeichen)

Wichtig ist zudem:
The external encoding is byte-based and can be chosen appropriately for the environment and for the texts to be handled. A variety of different character sets can be used for this external encoding (information that will not be exhaustively presented here–instead, a description of the major groups will suffice). All of the ASCII-based character sets fulfill one requirement: they are "filesystem safe." This means that the character '/' is used in the encoding only to represent itself. Things are a bit different for character sets like EBCDIC (Extended Binary Coded Decimal Interchange Code, a character set family used by IBM), but if the operating system does not understand EBCDIC directly the parameters-to-system calls have to be converted first anyhow.
Quelle: https://www.gnu.org/software/libc/manua ... Char-Intro (aus dem glibc-Handbuch)

Das alles scheint mir u.a. zu bedeuten:
1. Die Umwandlung von char* zu wchar_t* in meiner Funktion - das habe ich u.a. auch probiert - kann ich mir total schenken.
2. Ich kann ganz normal ein "char" mit einem character-literal vergleichen, also z.B. "if (*str == '.')" oder "if (*str == '0')" oder "if (*str == '/')".

In einer früheren Version des glibc-Manual stand sogar explizit:
Because the basic ASCII characters in the range from 0 to 0177 are so important, they stand for themselves in all multibyte character codes. That is to say, a byte whose value is 0 through 0177 is always a character in itself. The characters which are more than one byte must always start with a byte in the range from 0200 through 0377.
Quelle: http://kirste.userpage.fu-berlin.de/che ... bc_18.html
(Achtung: Die Zahlen dort sind nach dem Oktalsystem angegeben.)
Warum das so klar nicht mehr im aktuellen glibc-Handbuch steht, weiß ich nicht, liegt vielleicht daran, dass man nun noch mehr Spezialfälle berücksichtigen will?

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 08.03.2019 12:02:41

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
07.03.2019 10:42:32
1. Die Umwandlung von char* zu wchar_t* in meiner Funktion - das habe ich u.a. auch probiert - kann ich mir total schenken.
Ergänzung: Damit meinte ich nur: Es ist nicht zwingend notwendig. Es kann dennoch praktisch sein, wenn man ein Zeichen pro Einheit haben möchte. Ob das bei meiner Vergleichs-Funktion allerdings notwendig ist, hängt von der Herangehensweise ab.

Somit macht wchar_t wohl hauptsächlich für Programme wie Texteditoren Sinn.
Wobei - zu wchar_t sagt das glibc-Handbuch:
The ISO C90 standard, where wchar_t was introduced, does not say anything specific about the representation. It only requires that this type is capable of storing all elements of the basic character set. Therefore it would be legitimate to define wchar_t as char, which might make sense for embedded systems.

But in the GNU C Library wchar_t is always 32 bits wide and, therefore, capable of representing all UCS-4 values and, therefore, covering all of ISO 10646. Some Unix systems define wchar_t as a 16-bit type and thereby follow Unicode very strictly. This definition is perfectly fine with the standard, but it also means that to represent all characters from Unicode and ISO 10646 one has to use UTF-16 surrogate characters, which is in fact a multi-wide-character encoding. But resorting to multi-wide-character encoding contradicts the purpose of the wchar_t type.
Quelle: https://www.gnu.org/software/libc/manua ... Char-Intro

Wenn wchar_t nicht zwingend fähig ist, alle Zeichen zu enthalten, ist das natürlich keine Vereinfachung zum normalen "char"-Array, sondern eine Verschlechterung, weil man ja dennoch den überflüssig beschlagnahmten Speicherplatz hat.
Da wären dann möglicherweise so Neuigkeiten wie char32_t besser. Wobei es dazu soweit ich herausgefunden habe keine Funktionen gibt, außer welche, die multi-byte-strings zu char32_t-strings umwandeln oder umgekehrt. Ansonsten müsste man halt einen eigenen Datentyp definieren... Aber das hat dann nix mehr mit meiner compare-Funktion zu tun. Ist aber trotzdem interessant... :D

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 12.04.2019 13:50:28

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 23:14:51
Nennt sich Abitur oder so.
Successfully completed. :D
Meillo hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 22:53:50
warum es UTF-16-LE und UTF-16-BE gibt, aber nur ein UTF-8
Hm, nach allem, was ich bisher meine verstanden zu haben, kann man das so absolut nicht sagen. Denn byte order spielt ja nur dann eine Rolle, wenn wir Einheiten verwenden, die aus mehreren Bytes bestehen (also z.B. wchar_t, int, char16_t, char32_t). Diese können wir aber im Prinzip ebenso für UTF-8 verwenden, wie für UTF-16/-32 (es würde nur wenig Sinn ergeben). Genauso könnten wir (im Prinzip!) auch UTF-16 bzw. UTF-32 in einzelnen Bytes speichern (also als char-array in C). Nur dann müsste man darauf achten, statt der str*-Funktionen die mem*-Funktionen zu verwenden, also z.B. statt strcpy() memcpy(). Und man müsste natürlich die Länge der strings separat speichern.
Vorteil der Speicherung von UTF-16/-32 als char-array wäre, dass man sich nicht auf die Anzahl der Bytes in wchar_t verlassen müsste bzw. viele Bibliotheks-Funktionen zur Auswahl hat. Da allerdings diese Form des Umgangs mit diesen Encodings sehr wenig Sinn macht, wäre imho bewiesen, dass @meillo Recht hat, wenn er meint, dass UTF-8 das einzig wahre Encoding für das Unicode-Charset ist... :idea:

Benutzeravatar
novalix
Beiträge: 1909
Registriert: 05.10.2005 12:32:57
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: elberfeld

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von novalix » 12.04.2019 17:42:07

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
12.04.2019 13:50:28
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 23:14:51
Nennt sich Abitur oder so.
Successfully completed. :D
<AltHerrenGemoppere>Die lassen heutzutage aber auch jeden durchkommen.</AlteHerrenRaus> :mrgreen:
Gratulation!
Das Wem, Wieviel, Wann, Wozu und Wie zu bestimmen ist aber nicht jedermannns Sache und ist nicht leicht.
Darum ist das Richtige selten, lobenswert und schön.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 22.04.2019 08:59:49

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
12.04.2019 13:50:28
Meillo hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 22:53:50
warum es UTF-16-LE und UTF-16-BE gibt, aber nur ein UTF-8
Denn byte order spielt ja nur dann eine Rolle, wenn wir Einheiten verwenden, die aus mehreren Bytes bestehen (also z.B. wchar_t, int, char16_t, char32_t).
Ja.
Diese können wir aber im Prinzip ebenso für UTF-8 verwenden, wie für UTF-16/-32 (es würde nur wenig Sinn ergeben).
Nein, koennen wir nicht, denn: Wie gross waere denn die Einheit, die du lesen wuerdest, wenn du genau ein weiteres UTF-8-Zeichen *lesen* willst? ;-)
Genauso könnten wir (im Prinzip!) auch UTF-16 bzw. UTF-32 in einzelnen Bytes speichern (also als char-array in C).
Aber welches der zwei UTF-16-Bytes speicherst du dann als erstes ab? Erst das niederwertige oder erst das hoeherwertige? Da diese Entscheidung frei ist, haben wir eben LE und BE.


[...] wäre imho bewiesen, dass @meillo Recht hat, wenn er meint, dass UTF-8 das einzig wahre Encoding für das Unicode-Charset ist... :idea:
Klasse, dass nun auch bewiesen ist, dass ich Recht habe. ;-P

Der einzige Nachteil von UTF-8 ist, dass die Laenge eines Zeichens dynamisch ist und damit z.B. bei einem UTF-8 strlen() mehr Rechenarbeit noetig ist als bei eiem Festlaengen-Encoding. Auch die Datenstrukturen muessen dynamischer sein. Davor will man sich druecken. Das ist aber ein sich Druecken davor, die Realitaet zu akzeptieren. Festlaengen-Encodings entsprechen nicht der Natur der Sache und koennen darum nur vereinfachte und darum begrenzte Uebergangsloesungen sein. Wir koennten diese zeitweisen Uebergangsloesungen auch einfach mal bleiben lassen und es gleich richtig machen ...
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 22.04.2019 10:54:18

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Wie gross waere denn die Einheit, die du lesen wuerdest, wenn du genau ein weiteres UTF-8-Zeichen *lesen* willst?
Vier Bytes - der Rest würde wie bei UTF-16/-32 mit '\0' aufgefüllt werden. (Macht natürlich keinen Sinn.)
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Aber welches der zwei UTF-16-Bytes speicherst du dann als erstes ab? Erst das niederwertige oder erst das hoeherwertige? Da diese Entscheidung frei ist, haben wir eben LE und BE.
So könnte man ja (im Prinzip!) doch auch bei UTF-8 argumentieren, oder?
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Klasse, dass nun auch bewiesen ist, dass ich Recht habe. ;-P
Ich hoffe, dass Du mich nicht falsch verstanden hast. Ich freue mich halt immer, wenn ich meine, dass auch ich zu tieferer Einsicht gekommen bin. :wink:

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 22.04.2019 11:17:39

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 10:54:18
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Wie gross waere denn die Einheit, die du lesen wuerdest, wenn du genau ein weiteres UTF-8-Zeichen *lesen* willst?
Vier Bytes - der Rest würde wie bei UTF-16/-32 mit '\0' aufgefüllt werden. (Macht natürlich keinen Sinn.)
Vorsicht, hier darfst du nicht schlampig sein, in deinen Ueberlegungen.

Wenn du vier Bytes liest aus einem reinen ASCII-Text, dann hast du nicht ein, sondern vier Zeichen gelesen! Wenn du genau ein UTF-8-Zeichen lesen willst, dann geht das nicht en bloc. Du musst Byte fuer Byte lesen und zwar so lange, bis das hoechstwertigste Bit des Bytes 0 ist, dann ist das Zeichen vollstaendig. Das kann nach einem, nach zwei, nach drei oder nach vier Bytes der Fall sein. Wann es aber der Fall ist, kannst du erst wissen, wenn du die Bytes davor eines nach dem anderen gelesen hast.

Bislang denkst du zu sehr in Datenstrukturen in der Programmiersprache. dort kannst du natuerlich irgendwas mit Nullen auffuellen, beim Lesen muss man anders denken, denn wenn du vier Bytes von Stdin gelesen hast, dann sind die dort weg. Wenn du nur ein Zeichen lesen wolltest und es waren vier, dann hast du mit den restlichen drei ein Problem.

Die einzige Moeglichkeit wie man UTF-8-Zeichen lesen kann ist byteweise.

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Aber welches der zwei UTF-16-Bytes speicherst du dann als erstes ab? Erst das niederwertige oder erst das hoeherwertige? Da diese Entscheidung frei ist, haben wir eben LE und BE.
So könnte man ja (im Prinzip!) doch auch bei UTF-8 argumentieren, oder?
Nein, in UTF-8 ist definiert wie die einzig moegliche Reihenfolge ist. UTF-8 kann man auch nur byteweise lesen und byteweises Lesen hat immer eine definierte Reihenfolge.

UTF-8 ist in seiner Art wie `char'. Char kann man auf allen Systemen portabel speichern und lesen.

UTF-16 ist dagegen in seiner Art viel mehr wie `int'. Int kann nicht einfach von LE- auf BE-Systeme uebertragen werden.


Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Klasse, dass nun auch bewiesen ist, dass ich Recht habe. ;-P
Ich hoffe, dass Du mich nicht falsch verstanden hast. Ich freue mich halt immer, wenn ich meine, dass auch ich zu tieferer Einsicht gekommen bin. :wink:
Nee, nee, ich fand's nur lustig wie du das geschrieben hast. Wenn mir von nun an in irgendwelchen kontroversen Diskussionen irgendjemand mal widersprechen will, dann werde ich einfach darauf verweisen, dass du bewiesen hast, dass ich Recht habe. *hohoho* :-D Danke dafuer! ;-)
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 22.04.2019 11:49:47

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 11:17:39
Bislang denkst du zu sehr in Datenstrukturen in der Programmiersprache. dort kannst du natuerlich irgendwas mit Nullen auffuellen, beim Lesen muss man anders denken, denn wenn du vier Bytes von Stdin gelesen hast, dann sind die dort weg. Wenn du nur ein Zeichen lesen wolltest und es waren vier, dann hast du mit den restlichen drei ein Problem.

Die einzige Moeglichkeit wie man UTF-8-Zeichen lesen kann ist byteweise.
Ja klar, sorry, da war ich vorher echt unkonzentriert... :oops:

Antworten