string mit readline einlesen
-
Hallo Forum,
ich bin dabei mich mit C zu beschätigen.
Ich möchte nun eine kleines Programm schreiben, welches einen String entgegen nimmt, den Nutzer fragt ob der von ihm eingebene Strnig korrekt ist, und wenn nicht erneut nach dem String fragt.
Dazu folgendes:
int getBoxId(char *box_id) { char *confirm; while(confirm[0] != 'j' && confirm[0] != 'J') { box_id = readline("\nBitte Seriennummer angeben:\n"); printf("Seriennummer >> %s << korrekt?", box_id); input = readline(" [J/n]\n"); } return 1; }
Aufrufen tue ich die Funktion wie folgt:
char *box_id = (char*) malloc(BOX_ID_LENGTH); getBoxId(box_id);
Ich scheine nun aber irgendwas mit den Pointern falsch verstanden zu haben.
Der printf() Aufruf innerhalb der Funktion getBoxId() gibt die richtige Seriennummer aus.
Versuche ich aber nach dem Aufruf von getBoxId(box_id) box id auszugeben, kommt da nichts.
Was mache ich verkehrt?
Lg
MasseElch
-
Fangen wir mal mit dem Einfachsten an: readline gibt's ned.
Durch welche Geisterhand sich confirm füllen soll, bleibt auch Dein Geheimnis.In anderen Worten: Das compiliert nie und nimmer und da nehmen die meisten an, daß sie veralbert werden sollen.
Meine, den Fünfzeiler kriegt man schon hier am Board komplett unter und wenn er dann noch nicht tut, hilft jemand.
-
GNU readline malloc'd einen
char*
, den Du nach Gebrauch wieder freigeben musst.
von daher brauchst Du überhaupt keinmalloc()
, sondern nur einfree()
.
Insbesondere, wenn der User seine Eingabe berichtigen will, musst Du den alten string wieder deallozieren.Ausserdem willst Du ja, dass
box_id
im Anschluß auf den String zeigt. D.h. Du musstbox_id
per Referenz übergeben:
void getBoxId(char **box_id);
oder Du "returnst" das schlußendliche Ergebnis von readline():
char *getBoxId(void);
In Z. 5 deallozierst Du übrigens gleich mal den Zeiger
confirm
, der gar nicht initialisiert ist...
-
Furble Wurble schrieb:
In Z. 5 deallozierst Du übrigens gleich mal den Zeiger
confirm
, der gar nicht initialisiert ist...s/deallozierst/dereferenzierst/
-
Danke! Mit euren (teilweise sehr freundlich ausgedrückten) Hinweisen:
int getBoxId(char **box_id) { char *confirm = (char*) malloc(1); while(confirm[0] != 'j') { free(*box_id); free(confirm); *box_id = readline("\nBitte Serien-Nummer der Box angeben:\n"); printf("Seriennummer >> %s << korrekt?", *box_id); confirm = readline(" [j/n]\n"); } return 1; } int main() { [...] //Speicher für Serien-Nummer char *box_id; getBoxId(&box_id); printf("\nNutze Seriennummer %s", box_id); [...] }
-
Da fehlt was:
Es funktioniert jetzt. Vielen Dank für die Hinweise.
Ist der Code an sich denn so "vernünftig"?
Ich weiß nicht so recht ob das mit dem malloc bei initialisiren richtig ist.
MasseElch
-
MasseElch schrieb:
int getBoxId(char **box_id) { char *confirm = (char*) malloc(1); while(confirm[0] != 'j') { free(*box_id); free(confirm); *box_id = readline("\nBitte Serien-Nummer der Box angeben:\n"); printf("Seriennummer >> %s << korrekt?", *box_id); confirm = readline(" [j/n]\n"); } return 1; } int main() { [...] //Speicher für Serien-Nummer char *box_id; getBoxId(&box_id); printf("\nNutze Seriennummer %s", box_id); [...] }
Ja. Das geht doch schon in die richtige Richtung.
Der Wert von vonconfirm[0]
in Z. 5 ist nicht definiert. Gleiches gilt für*box_id
in Z. 6 - auf keinen Fall darfst Du sofree()
auf*box_id
aufrufen - das ließe sich allerdings Durch einchar* box_id=NULL;
in Z. 22 kitten.free()
auf einen NULL-Zeiger ist eine no-op.Am Ende von
getBoxId()
musst Du aufjedenfall den confirm-String noch freigeben. (s.u.)Ich kann mir vorstellen, dass Du mit ein wenig Logik und Umstellungen das ganze gut hinbekommst - auch ohne das dummy
malloc()
vonconfirm
.Evtl. hilft es auch die ja/nein frage in eine extra Funktion auszulagern á la
bool again(); // readline(), freigeben, true oder false zurueckgeben
.
-
Erst Mal vielen Dank für die ganze Hilfe
Folgendes habe ich nun gebastelt:
int getBoxId(char **box_id) { char *confirm; int ret = 0; *box_id = readline("Bitte Serien-Nummer der Box eingeben:\n"); printf("Serien-Nummer >> %s << korrekt?", *box_id); confirm = readline(" [j/n]\n"); ret = confirm[0] != 'j'; free(confirm); return ret; } int main() { [...] //Speicher für Serien-Nummer char *box_id; while(getBoxId(&box_id)); printf("\nNutze Seriennummer >> %s <<\n\n", box_id); [...] free(box_id); return 0; }
Jetzt wird jedes Mal nach dem confirm der SPeicher wieder freigegeben, genauso auch am Ende, bevor das Programm terminiert der Speicher von box_id.
So korrekt?Kann man das mit dem while so machen? Oder ist sowas auch nicht den Konventionen entsprechend oder Ähnliches?
MasseElch
-
Aber wenn ich mich jetzt versehe bei der Eingabe wird der alte
box_id
string nie freigegeben, oder?Und zu allem Überfluß kann
readline()
auch noch NULL zurückgeben...Eine Menge Stolperfallen.
Aber letztlich ein Logikproblem und Du bist ja schon auf dem richtigen Weg...
-
OK, wußte nicht, daß das hier das GNU-Libs- Forum ist. Bitte sowas in einem Kommentar vermerken oder den inlude hinschreiben. Oder beides.
Noch 'ne Unschönheit: malloc() bitte nicht typisieren, das ist ganz schnöde eine Startadresse auf ein Stückchen reservierten Speichers, sofern nicht NULL. Die Typisierung erfolgt durch die Speicherung auf den Pointer.