Frage zu scanf und printf



  • Hallo Zusammen,

    wenn ich scanf benutze um z.B. zahl2 einen Wert per Tastatureingabe zuzuweisen und zahl2 nicht irgendwo im code in einer printf-Anweisung steht, übergeht mein Compiler elegant die erste scanf-Anweisung und springt direkt zur nächsten printf Anweisung, ohne dass ich Gelegenheit bekomme, eine Wert für Zahl2 einzutippen. Kann mir das jemand erklären? Hab bisher nur c++ programmiert und dort gibts ja cin und cout.

    Beispiel:

    signed int Zahl,Zahl1;
    float Zahl2;
    
    void main(void)
    {
      printf("float zahl eingeben: \n");   
      scanf("%f",&Zahl2);
      //printf("%f\n", Zahl2);
    
      printf("int zahlen eingeben: \n");
      scanf("%d%d",&Zahl,&Zahl1);
      printf("%d \n %d \n ",&Zahl,&Zahl1);
    
    }
    


  • Also das kann ich mit meinem Compiler (VS2005) nicht bestätigen. scanf wird korrekt ausgeführt und die float-Variable wird eingelesen und gespeichert. Und das unabhängig von dem auskommentierten printf-Aufruf. Ich habe sowohl den C- als auch den CPP-Compiler ausprobiert.

    Hast du den Code zufällig gekürzt und "unwichtige" Stellen vor uns verborgen?



  • xkris schrieb:

    wenn ich scanf benutze um z.B. zahl2 einen Wert per Tastatureingabe zuzuweisen und zahl2 nicht irgendwo im code in einer printf-Anweisung steht, übergeht mein Compiler elegant die erste scanf-Anweisung und springt direkt zur nächsten printf Anweisung, ohne dass ich Gelegenheit bekomme, eine Wert für Zahl2 einzutippen. Kann mir das jemand erklären?

    Ob der Benutzer die Möglichkeit zur Eingabe bekommt hat nichts mit anderem Code als dem scanf( ) -Aufruf zu tun. Es könnte höchstens sein, dass in stdin vor scanf( ) bereits ein Newline steht, was dazu führt, das scanf( ) das schon vorhandene '\n' als Ende der Eingabe interpretiert und somit der Benutzer das nachsehen hat. Abhilfe schafft hier das leeren von stdin vor der Eingabe:

    void flush_stdin( void )
    {
        setvbuf( stdin, 0, _IONBF, 0 );
        setvbuf( stdin, 0, _IOFBF, BUFSIZ );
    }
    

    xkris schrieb:

    Hab bisher nur c++ programmiert und dort gibts ja cin und cout.

    void main( void ) ist in beiden Quatsch!

    xkris schrieb:

    signed int Zahl,Zahl1;
    float Zahl2;
    

    Warum alles global? Den signed -Modifizierer kannst Du dir sparen.

    xkris schrieb:

    void main(void)
    

    Kein Kommentar.

    xkris schrieb:

    printf("%d \n %d \n ",&Zahl,&Zahl1);
    

    Ich glaube nicht, das du Adressen als Decimal ausgeben willst. Ich glaub' noch nichtmal, das Du Adressen ausgeben willst... 😉

    cheers, Swordfish



  • Hallo und danke für eure Antworten

    xkris schrieb:

    Hab bisher nur c++ programmiert und dort gibts ja cin und cout.

    void main( void ) ist in beiden Quatsch!

    was ist quatsch?

    xkris schrieb:

    signed int Zahl,Zahl1;
    float Zahl2;
    

    Warum alles global? Den signed -Modifizierer kannst Du dir sparen.

    Global weil der Compiler meckert, wenn ichs innerhalb der "Main" deklariere, keine Ahnung warum. Dass ich signed weglassen kann weiss ich.

    xkris schrieb:

    void main(void)
    

    Kein Kommentar.

    xkris schrieb:

    printf("%d \n %d \n ",&Zahl,&Zahl1);
    

    Ich glaube nicht, das du Adressen als Decimal ausgeben willst. Ich glaub' noch nichtmal, das Du Adressen ausgeben willst... 😉

    cheers, Swordfish

    Doch, will ich. Darauf würde sich auch meine nächste Frage beziehen. Wenn ich mir die Adressen Hexadezimal ausgeben lasse, ist alles so wie ich es erwarte. Lass ich sie mir hingegen dezimal anzeigen, sind die Adressen negativ. Aber ich glaube das hat was damit zu tun, wie die Speicherverwaltung das skaliert. Da wird der Speicherbereich bei dezimaler Ausgabe offensichtlich so verschoben , das die untere Hälte der Adressen negative ist.

    Ich benutze die µc-Entwicklungsumgebung von Keil (kostenlose Testversion). Wenn ich das Ganze im Dev C++ schreibe funktioniert alles so wie ich es erwarte 😞



  • xkris schrieb:

    xkris schrieb:

    Hab bisher nur c++ programmiert und dort gibts ja cin und cout.

    void main( void ) ist in beiden Quatsch!

    was ist quatsch?

    Es gibt keine main-Funktion ohne Rückgabewert. Die meisten Comiler akzeptieren das zwar, die korrekte Definition verlangt aber, dass main einen int-Wert zurückgibt. Diesen kann man z.B. in Batch-Dateien auswerten.



  • xkris schrieb:

    xkris schrieb:

    signed int Zahl,Zahl1;
    float Zahl2;
    

    Warum alles global? Den signed -Modifizierer kannst Du dir sparen.

    Global weil der Compiler meckert, wenn ichs innerhalb der "Main" deklariere, keine Ahnung warum. Dass ich signed weglassen kann weiss ich.
    [/qoute]

    Bei dem Beispiel, dass du gepostet hast, garantiert nicht! Warum sollte er meckern bzw. was genau sagt er denn?

    EDIT: Ach ja, dein "Adressen sind dezimal negativ"-Problem sollte sich wahrscheinlich erledigen, wenn du die Variablen als unsigned deklarierst. Sonst wird das höchste Bit als Indikator für das Vorzeichen interpretiert.



  • _matze schrieb:

    Es gibt keine main-Funktion ohne Rückgabewert. Die meisten Comiler akzeptieren das zwar, die korrekte Definition verlangt aber, dass main einen int-Wert zurückgibt. Diesen kann man z.B. in Batch-Dateien auswerten.

    <axt:spalten target="Haare">
    Der Standard verlangt, dass main mit Integer-Rückgabe definiert wird. Die Rückgabe selbst (return-Statement) darf man seit C99 (nur in main) weglassen.
    </axt:spalten>

    xkris schrieb:

    Doch, will ich. Darauf würde sich auch meine nächste Frage beziehen. Wenn ich mir die Adressen Hexadezimal ausgeben lasse, ist alles so wie ich es erwarte. Lass ich sie mir hingegen dezimal anzeigen, sind die Adressen negativ. Aber ich glaube das hat was damit zu tun, wie die Speicherverwaltung das skaliert. Da wird der Speicherbereich bei dezimaler Ausgabe offensichtlich so verschoben , das die untere Hälte der Adressen negative ist.

    Das hat was damit zu tun, wie printf arbeitet. Da es bei Funktionen mit variablen Argumentlisten keine Möglichkeit gibt festzustellen, welchen Typ ein einzelnes Argument hat, muss printf sich auf den Formatstring verlassen. Da "%d" für signed integer steht, liest printf aus den Argumenten zunächst sizeof(int) Bytes, und interpretiert diese dann als vorzeichenbehafteten Integer.

    Um also die korrekte Ausgabe zu erhalten, musst Du entweder den Parameter in den Typ den "%x" erwartet umwandeln, oder den korrekten "%x" Modifizierer benutzen. Zum Beispiel:

    printf("%u", (unsigned) &Zahl); // %u erwartet unsigned int, aber vorsicht: kann in die Hose gehen, da sizeof(int*) größer als sizeof(int) sein kann
    printf("%p", &Zahl); // %p erwartet pointer
    


  • LordJaxom schrieb:

    <axt:spalten target="Haare">

    *rofl*

    Dann spalte ich mal weiter: Läuft die Anwendung nicht in einem "Hostet Environment" darf der Entry Point anders aussehen.

    cheers, Swordfish


Anmelden zum Antworten