Diverse Fragen (Style)
-
Jetzt tut sich bei mir doch noch eine Frage auf:
Wie liest man denn in C sauber User-Input ein?
Visual Studio (2015) z.B. sieht es tatsächlich als Fehler an, wenn man einfach scanf verwendet. Das kompeliert nicht einmal.
Ich will jetzt aber auch nicht scanf_s verwenden, da das ja scheinbar von MC selber ist (obwohl es wohl in C11 auch implementiert ist?)
Gibt's denn jetzt eine Fausregel wie man User-Input liest? Ist scanf nicht völlig ausreichend, solange man es vorsichtig verwendet?
-
Dass das reine Verwenden von scanf ein Fehler ist, ist mir neu. Vermutlich werden bei dir alle Warnungen als Fehler behandelt, wobei bei der Benutzung von scanf eine Sicherheits-Warnung und somit ein Fehler generiert wird.
-
Tatsächlich ist es jetzt nicht mehr der Fall, ein paar Tage zuvor war es aber definitiv eine Fehler.
Also ist scanf durchaus in Ordnung zum Einlesen, solange man acht gibt?
-
Ja, ist in Ordnung.
Aber Nutzer sind sehr Kreativ mit Fehlbedienungen (Falsche Zeichen, zuviel Zeichen, falscher Wertebereich)
Um diese abzusichern ist ein einfaches scanf nicht geeignet.Da man aber für Nutzerinteraktion nur noch selten direkte Eingaben über die Konsole hat, spielt das kaum noch eine Rolle.
-
Danke für deine Antwort!
Sofern ich also Daten vom User über die Konsole einlese würde ich in einem "echten" Programm also sie wohl erst "neutral" lesen und dann analysieren, um zu sehen ob ich sie so akzeptieren will / kann?
-
Das kommt auch darauf an, wie gutmütig dein Programm sein soll.
Wenn der Nutzer zu blöd ist, die richtigen Daten einzugeben, dann geht auch "Garbage in, garbage out"
Das Programm darf mit falschen Daten aber nicht Amok laufen (abstürzen).
-
DirkB schrieb:
Das Programm darf mit falschen Daten aber nicht Amok laufen (abstürzen).
Doch. Besser abstürzen (möglichst noch mit aussagekräftiger Meldung) als unbemerkt mit falschen Daten weitermachen.
Also ist scanf durchaus in Ordnung zum Einlesen, solange man acht gibt?
Ja. scanf_s ist Nonsens, die dort für %c %s %[] vorgesehenen Extra-Parameter hat scanf bereits als Feldlänge.
Einzig könnte ich mir einen Vorteil dadurch vorstellen, dass bei scanf_s der Compiler eine fehlende Längenbegrenzung anmahnen könnte, man also nochmal explizit vom Compiler darauf hingewiesen wird, sich um die Längenbegrenzung Gedanken zu machen.Da man aber für Nutzerinteraktion nur noch selten direkte Eingaben über die Konsole hat, spielt das kaum noch eine Rolle.
Spielt bei stdin-Umlenkung via | und < nach wie vor eine Rolle, insbesondere bei automatisierter Kommandozeilenverarbeitung.
Sofern ich also Daten vom User über die Konsole einlese würde ich in einem "echten" Programm also sie wohl erst "neutral" lesen und dann analysieren, um zu sehen ob ich sie so akzeptieren will / kann?
Das ist ja das Problem: gerade das "neutrale" Einlesen (d.h. üblicherweise in einen String) kann zu Überläufen führen, wenn dieser dann unbemerkt bleibt, fallen die Ergebnisse dann vielleicht einem mitdenkenden Anwender am Bildschirm auf, aber sie fallen niemals auf in automatischen Batchläufen; dort sollen sie dann abstürzen s.o.
-
Wutz schrieb:
Doch. Besser abstürzen (möglichst noch mit aussagekräftiger Meldung) als unbemerkt mit falschen Daten weitermachen.
Wenn man noch eine Fehlermeldung hin bekommt, kann man das Programm auch beenden.
-
Nun gut, ob man das Programm jetzt crashen lassen will bzw bei falscher Eingabe beendet oder eine Fehlermeldung ausgibt hängt denke ich mal vom Programm ab.
Da ich hier in der Uni erst mal nur so kleine Snippets abgeben muss nehme ich mal stark an dass sowas wie user eingabe auf herz und Niere prüfen zu vernachlässigen ist.
Ich merke mir aber dass ich im Ernstfall schauen sollte, dass ich die Eingaben überprüfe bevor ich weiter mache.
-
Mir kam jetzt noch eine Frage auf:
1. Tenärer Operator - ist der grundsätzlich böse oder darf man ihn dezent anwenden?
Bsp. return a == b ? c : b;
Das würde ich jetzt spontant schreiben, anstatt per if-else die jeweiligen return Werte hinzuschreiben.
C ist hierbei eine konstante also auch kein Ausdruck.Hier gibts kein Gesetzt, mich würd interessieren ob Ihr persönlich das als unsauber sehen würde.
2. "Überladene" Rückgabewerte - Wir sollten hier mal (etwas her) ein kleines Snippet abgeben, in der "Freund"-Zahlen berechnet werden sollen.
So soll der Benutzer Ober- und Untergrenze eingeben und man soll dann für jede Zahl in diesem Bereich schauen, ob diese Zahl eine Freundzahl besitzt und wenn sie eine solche besitzt beide ausgeben (x ist freund von y).
Dazu schrieb ich mir also eine Funktion im Stil
int friendOf(int x)
.Die returned den friend von x oder 0 wenn es keinen gibt.
Dazu hieß es, der Rückgabewert der Funktion sei "überladen" also mehrdeutig, nicht eindeutig, nicht intuitiv und daher schlecht / unsauber.
Würdet ihr da zustimmen? Ich bin das Verhalten eigentlich gewohnt - beispielsweise aus find() Funktionen usw.
Mir würde spontan dann auch gar nicht einfallen, wie es schöner / sauberer gelöst wäre.
-
1. Klar kannst du den benutzen, solange es nicht zu unübersichtlich wird.
2. Versteh ich nicht ganz...
-
Danke für deine Antwort
Zu 1.:
Okay, dann bin ich beruhigt. Ich finde den an manchen Stellen eigentlich echt angenehm und auch übersichtlich zu benutzen.
Aber ich dachte, dass er eventuell allgemein verpönt ist, weil der Dozent damals schon sehr abgeneigt reagierte ("Wenn man den Operator verwendet, dann weiß man schon, dass was schief gelaufen ist - den benutzt man nur, wenn man gar nicht mehr weiter weiß").Zu 2.:
So genau weiß ich das ehrlich gesagt auch gar nicht.Ich denke, dass er mit "überladen" meinte, dass der Rückgabe-wert der Funktion zwei verschiedene Bedeutungen haben "Kann".
Einmal gibt er den "Freund" der übergebenen Zahl zurück und einmal fungiert er sozusagen als "hasFriend" indem er 0 zurück gibt, wenn kein "Freund" gefunden.Find ich jetzt aber auch komisch, ich dachte das wäre Usus.
-
Zu 2: Das ist tatsächlich unschön, aus den genannten Gründen. Man kann in deinem Beispiel nicht unterscheiden, ob die Grenze nun 0 ist oder ob ein Fehler aufgetreten ist. Es wird manchmal trotzdem gemacht, vor allem bei älteren Funktionen aus der Standardbibliothek, die man sich nicht unbedingt zum Vorbild nehmen sollte.
Mögliche Abhilfen in diesem Fall:
-Funktionsergebnis über Funktionsparameter zurück geben und Fehlercode als Rückgabewert der Funktion
-Globaler Fehlerindikator, wie errno.
-sich mit longjmp so etwas wie die Exceptions aus anderen Sprachen selber programmieren
-
Also tatsächlich gilt das, sehr interessant!
Die Alternativen überraschen mich allerdings etwas, nur um das jetzt richtig verstanden zu haben:
Vorzuziehen wäre in diesem Fall also solch eine Konstruktion:
int friendOf(int param, int* result) { // Success *result = friendValue; return 1; // failure return 0; } // main if (friendOf(i, &result)) { printf("%d is friend of %d\n", i, result); }
Finde ich überraschend und entgeht auch meiner Intuition, aber da ich auf keine wirkliche Programmier-Erfahrung zurückblicken kann, bin ich durchaus gewillt es zu glauben
Die Sache mit dem Exceptions nachbauen wäre wohl für Snippets ein overkill. Findet das denn sonst bei euch Verwendung?
-
Krieg ich hier noch ein abschließendes Fazit bitte?
Ich würd sehr gerne wissen ob ich richtig verstanden habe, wie der bevorzugte Weg auszusehen hat!
-
Immer sachte mit deinen Ansprüchen.
Du willst eine Druckbetankung als Extrakt der dir hier gegebenen Antworten angereichert mit allen Erfahrungen langjähriger Praktiker und vielleicht noch vollständige Auflistungen aus der Standardbibliothek, wo und warum es dort anders gemacht wird?
Was zahlst du?
-
Ich hätte ehrlich gesagt eine abschließende Meinung zu der konkreten, genannten Thematik.
Ich brauche keine Auflistung irgendwelcher Standardfunktionen mit Erklärung.
SeppJ hatte hier auf mein konkretes Beispiel reagiert und bessere Alternativen genannt - ich würde jetzt nur noch gerne wissen ob diese richtig verstanden habe.
Ich weiß jetzt leider nicht, was dich zu deinem Beitrag bewegt hat, aber ich hoffe mal, dass es ehrliches Missverständnis wär.
-
Ja, dein Beispiel entspricht einer der drei genannten Methoden.
-
SeppJ schrieb:
Ja, dein Beispiel entspricht einer der drei genannten Methoden.
Danke.
-
@Diverses damit musst du leben. Wutz gibt immer so qualitativ hochwertige Antworten auf Leute die es nicht besser wissen wie er