scanf



  • Hi ho!
    Ich will mit scanf was von der Tastatur lesen und das dann in einen char* reinschreiben.

    char* string = NULL;
    	string = (char*) malloc(128*sizeof(char));
    	scanf("%s",string);
    

    Warum kann ich nur bis zum ersten Leerzeichen in den String schreiben?
    Mach ich was falsch? Mit gets() gehts bei mir ja auch ohne probleme



  • "%[^\n]s" statt "%s" im Format sollte helfen.
    Wenn du aber ganze Strings liest, würde ich dir man: fgets(3) empfehlen.



  • scanf kann nunmal nur bis zum ersten leerzeichen einlesen nutze fgets() oder der gleichen ...

    grussle TDO



  • Ausserdem solltest du die Rückgabe von malloc() nicht casten. Und sizeof(char) ist immer 1.



  • TactX schrieb:

    Ausserdem solltest du die Rückgabe von malloc() nicht casten. Und sizeof(char) ist immer 1.

    das Problem an dem Code ist _nicht_ das Casten und sizeof(char), immerhin ist das nicht falsch. Was dumm ist, ist dass der nicht überprüft, ob malloc NULL zurückgeliefert hat und das ist wichtiger als die unnötige cast-Geschichte.



  • Stimmt. Ich vergesse immer das zu erwähnen 🙄



  • @TactX:
    Ich finde es nicht gut, dass du Leute zum nichtcasten (tolle Wortkreation :D) bewegen willst. Es ist doch gut, wenn es getan wird. Ich hab schon genügend besch..... Code gesehen, den ich in mühevoller Arbeit auseinander gepflückt habe. Dann lieber ein bisschen zu viel als zu wenig. 😉



  • Maffe001 schrieb:

    @TactX:
    Ich finde es nicht gut, dass du Leute zum nichtcasten (tolle Wortkreation :D) bewegen willst.

    Ich schon.

    Maffe001 schrieb:

    Es ist doch gut, wenn es getan wird.

    Nein. Casts sind idR ein Ausruck für schlechtes Design und nur in seltenen Fällen wirklich notwendig.

    Maffe001 schrieb:

    Ich hab schon genügend besch..... Code gesehen, den ich in mühevoller Arbeit auseinander gepflückt habe. Dann lieber ein bisschen zu viel als zu wenig. 😉

    Lieber vorher nachdenken anstatt sofort zu casten. 😉



  • Danke für den tip mit "%[^\n]s" statt "%s" es geht!

    Andere Frage was ist an dem casten in diesem Fall so schlimm??
    Bitte mal mit einem handfestem Argument!
    Ohne cast meckert bei mir der Compiler?



  • Karl Napf schrieb:

    Andere Frage was ist an dem casten in diesem Fall so schlimm??

    Die allgemeine Syntax dieser Funktionen zur dynamischen Speicherverwaltung (in der stdlib.h enthalten) sehen ja folgendermaßen aus ...

    void* malloc( size_t size ); 
    void* realloc( void* Ptr, size_t size ); 
    void* calloc( size_t nMemb, size_t size );
    

    ... der Rückgabewert dieser Funktionen ist also void*, und dieser kann vom Compiler implizit gecastet werden. Bisher also nichts weltebewegendes. Aber: wenn man vergisst die stdlib.h einzubinden, dann haben diese Funktionen keinen Prototypen/Funktionsdefinition mehr. Das hat zu Folge, dass der Compiler von einer Definition der Art ...

    extern int malloc();
    

    ... ausgeht. Also der Rückgabewert ein int ist, und ein int ja was Anderes als ein int* ist (deshalb auch die Warungen vom Compiler)!! Gefährlich ist das casten nur, wenn man die stdlib.h nicht einbindet. Sollte die stdlib.h jedoch eingebunden sein, dann ist ein Casting nur überflüssig.

    Jetzt wollen wir das Programm aber auf eine andere Plattform laufen lassen, und dort ist z.B.

    if( sizeof( int ) != sizeof( void* ) ) 
       printf( "Krachbumm ... alles hin !!" );
    

    Tja ... das wars dann (wenn ein int im Speicher anders abgelegt wird, als ein Pointer).
    Wenn man nicht castet (und vielleicht die stdlib.h nicht eingebunden hat), dann kann der Compiler u.U. den Fehler feststellen. In diesem Fall können übrigens malloc() auch so aufrufen:

    malloc( "Das ist malloc" )
    

    Also sollten wir das Casten lieber lassen sein.

    Hoffe mich einigermaßen verständlich ausgedrückt zu haben :), wenn nicht - oder wenn ich sogar falsch liege - bitte revidiert diese Aussage.

    btw: so langsam wäre die Frage doch wohl auch was für die FAQ - oder ?



  • Karl Napf schrieb:

    Ohne cast meckert bei mir der Compiler?

    Falls du <stdlib.h> doch eingebunden hast, kann es sein, dass du mit 'nem C++ Compiler rangehst? Dort ist ein expliziter Cast nämlich notwendig.



  • Karl Napf schrieb:

    Ohne cast meckert bei mir der Compiler?

    du kompilierst auch C Code mit einem C++ Compiler, das ist nicht gut.

    Karl Napf schrieb:

    Andere Frage was ist an dem casten in diesem Fall so schlimm??
    Bitte mal mit einem handfestem Argument!
    Ohne cast meckert bei mir der Compiler?

    Die Sprache C konvertiert Datentypen von void* auf anderes_datentyp* automatisch, deshalb ist in C nicht notwenig, Ausgabe von void* Pointer zu casten. Das ist ein Fakt und das ist nun mal so in C.

    void* tuwasmitdemspeicher()
    {/* egal wie die hier aussieht */}
    
    void foo()
    {
       char* a = tuwasmitdemspeicher();
       int* b = tuwasmitdemspeicher();
       long* c = tuwasmitdemspeicher();
       ...
    }
    

    usw ist in C legal, weil C diese void* -> char*, void* -> int*, void* -> long* Geschichte selber macht, ein cast ist an dieser Stelle nicht notwenig.

    efährlich ist das casten nur, wenn man die stdlib.h nicht einbindet. Sollte die stdlib.h jedoch eingebunden sein

    ...

    Wenn man nicht castet (und vielleicht die stdlib.h nicht eingebunden hat), dann kann der Compiler u.U. den Fehler feststellen. In diesem Fall können übrigens malloc() auch so aufrufen:

    wer stdlib.h nicht einbindet, aber malloc/free benutzt, ist ein schlechter Programmier und sollte zuerst C lernen, bevor er ich wagt, ein C Programm mit malloc zu schreiben. Dieses Argument funktioniert bei jeder Funktion, nicht nur bei malloc. 😕

    Ich finde es nicht gut, dass du Leute zum nichtcasten (tolle Wortkreation ) bewegen willst

    In C muss man da nicht casten, und das ist nun mal so. Wir sind im C Forum und nicht im C++ Forum.



  • supertux schrieb:

    wer stdlib.h nicht einbindet, aber malloc/free benutzt, ist ein schlechter Programmier und sollte zuerst C lernen, bevor er ich wagt, ein C Programm mit malloc zu schreiben. Dieses Argument funktioniert bei jeder Funktion, nicht nur bei malloc. 😕

    Da stimme ich dir vollkommen zu. Das dieses Argument nicht nur bei malloc zutrifft ist mir auch klar - nur habe ich mich hier explizit auf diesen thread hier bezogen, und der bezog sich nun mal auf die dynamsische Speicherverwaltung 😉

    So long ...


Anmelden zum Antworten