C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Frage zu kleinem Programm

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Daniel Brandelt
Guest





PostPosted: Thu Nov 20, 2003 7:40 am    Post subject: Frage zu kleinem Programm Reply with quote



Hallo, ich bin c++ Anfänger und habe eine Frage zu dem unten aufgeführten
Programm.
Warum wird die Schleife immer 2 mal durchlaufen, wenn man in der Konsole
etwas anderes als "q"
eingibt ?


#include <stdio.h>
int main( int argc, char *argv[] )
{
char quit;
quit = '';
while (quit != 'q')
{
printf( "Hello ! This is a console app.n");
printf( "To create a console, go to Project Options and select n");
printf( "'Win32 Console'.n" );
printf( "Press q to quit " );
scanf( "%c", &quit );
}
return 0;
}

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Ralf Bartzke
Guest





PostPosted: Thu Nov 20, 2003 9:43 am    Post subject: Re: Frage zu kleinem Programm Reply with quote



Daniel Brandelt schrieb:
Quote:
Hallo, ich bin c++ Anfänger und habe eine Frage zu dem unten aufgeführten
Programm.
Warum wird die Schleife immer 2 mal durchlaufen, wenn man in der Konsole
etwas anderes als "q"
eingibt ?


#include int main( int argc, char *argv[] )
{
char quit;
quit = '';
while (quit != 'q')
{
printf( "Hello ! This is a console app.n");
printf( "To create a console, go to Project Options and select n");
printf( "'Win32 Console'.n" );
printf( "Press q to quit " );
scanf( "%c", &quit );
}
return 0;
}

Weil scanf("%c") nur ein einzelnes Zeichen von der Konsole liest. Der

Rest (Returnzeichen?) bleibt im Eingabepuffer liegen und wird beim
folgenden Durchlauf gelesen.

Ralf

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Marcel Müller
Guest





PostPosted: Thu Nov 20, 2003 9:47 am    Post subject: Re: Frage zu kleinem Programm Reply with quote



Hallo,

Daniel Brandelt wrote:

Quote:
Hallo, ich bin c++ Anfänger und habe eine Frage zu dem unten aufgeführten
Programm.

Das Programm ist kein C++, sondern ein C-Programm.

Quote:
Warum wird die Schleife immer 2 mal durchlaufen, wenn man in der Konsole
etwas anderes als "q"
eingibt ?

Weil das erste Zeichen beispielsweise 'A' ist und das zweite die
Enter-Taste (0x13), dann erst wird das 'q' entgegengenommen.
--
Marcel Müller

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Christoph Rabel
Guest





PostPosted: Thu Nov 20, 2003 9:53 am    Post subject: Re: Frage zu kleinem Programm Reply with quote

Daniel Brandelt wrote:
Quote:
Hallo, ich bin c++ Anfänger und habe eine Frage zu dem unten aufgeführten
Programm.
Warum wird die Schleife immer 2 mal durchlaufen, wenn man in der Konsole
etwas anderes als "q"
eingibt ?

scanf( "%c", &quit );

Weil diese Zeile genau 1 Zeichen aus dem Buffer holt. Was du
vergisst, ist das im Tastaturbuffer auch noch das Enter
steht. Beim nächsten Schleifendurchlauf wird eben das Enter
aus dem Buffer geholt, in quit hineingeschrieben und erst
jetzt ist der Buffer leer.

Du musst also noch das Enter aus dem Buffer holen.

z.B. indem du die Zeile so änderst:

scanf( "%cn", &quit );

Hier versucht das scanf ein Zeichen und ein Enter zu parsen.

Das scheitert z.B. wenn du zwei Zeichen und ein Enter eingibst.

Du musst hier auch den Rückgabewert von scanf prüfen, ob das
Einlesen funktioniert hat.


Generell:

Bite führe Einrückungen bei deinem Sourcecode ein, es ist
sonst sehr mühsam zu lesen:

#include <stdio.h>

// Bitte beachte, das das ein C Header ist. In C++ heisst
// der Header <cstdio>

int main( int argc, char *argv[] )
{
char quit;
quit = '';
while (quit != 'q')
{
printf( "Hello ! This is a console app.n");
printf( "To create a console, go to Project Options and
select n");
printf( "'Win32 Console'.n" );
printf( "Press q to quit " );
scanf( "%c", &quit );
}
return 0;
}

Weiters, als erste Verbesserung würde ich nicht mit scanf
sondern eher mit fgets/sscanf arbeiten.

Als zweites würde ich ganz auf die C Funktionen verzichten
und mit streams arbeiten.

mfg

Christoph

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Daniel Brandelt
Guest





PostPosted: Thu Nov 20, 2003 10:31 am    Post subject: Re: Frage zu kleinem Programm Reply with quote

Quote:
Weil diese Zeile genau 1 Zeichen aus dem Buffer holt. Was du
vergisst, ist das im Tastaturbuffer auch noch das Enter
steht. Beim nächsten Schleifendurchlauf wird eben das Enter
aus dem Buffer geholt, in quit hineingeschrieben und erst
jetzt ist der Buffer leer.

Du musst also noch das Enter aus dem Buffer holen.

z.B. indem du die Zeile so änderst:

scanf( "%cn", &quit );

Hier versucht das scanf ein Zeichen und ein Enter zu parsen.

Das scheitert z.B. wenn du zwei Zeichen und ein Enter eingibst.

Du musst hier auch den Rückgabewert von scanf prüfen, ob das
Einlesen funktioniert hat.

Danke für die Info !
Genau das wollte ich wissen. :-)

Quote:
Generell:

Bite führe Einrückungen bei deinem Sourcecode ein, es ist
sonst sehr mühsam zu lesen:

Werd ich in Zukunft machen.

Quote:

Weiters, als erste Verbesserung würde ich nicht mit scanf
sondern eher mit fgets/sscanf arbeiten.

Als zweites würde ich ganz auf die C Funktionen verzichten
und mit streams arbeiten.
Daran werd ich mich auch halten --> mir ging es in diesem Fall um das

Verständniss.

MfG
Daniel

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Horst Kraemer
Guest





PostPosted: Thu Nov 20, 2003 1:05 pm    Post subject: Re: Frage zu kleinem Programm Reply with quote

On Thu, 20 Nov 2003 08:40:18 +0100, "Daniel Brandelt"
<thinkman99 (AT) gmx (DOT) de> wrote:

Quote:
Hallo, ich bin c++ Anfänger und habe eine Frage zu dem unten aufgeführten
Programm.
Warum wird die Schleife immer 2 mal durchlaufen, wenn man in der Konsole
etwas anderes als "q"
eingibt ?

Das haben bereits andere verkuendet. In C wuerde ein korrektes
Programm etwa so aussehen


#include <stdio.h>

int main( int argc, char *argv[] )
{
int quit,test;

quit=0;

/* Ausser beliebigen Zeichenfolgen, die mit q beginnen,
wird auch EOF als Auffordung zum Verlassen akzeptiert,
denn wenn der Benutzer ein EOF-Signal eingegeben hat,
(unter Win F6<RETURN> oder ^Z<RETURN>) kann er danach gar
nichts mehr eingegeben und wird warten bis in alle
Ewigkeit... Um ein EOF zu lesen, muessen wir quit und test
als int deklarieren, da EOF ein int und kein Zeichen ist.
*/

while (quit!='q' && quit!=EOF)
{
printf( "Press q to quit n" );
quit = getchar();
/* Wenn das einzige Zeichen der Zeile n ist
oder EOF vorliegt, sind wir fertig. Andernfalls
den Rest der Eingabezeile bis n oder EOF weglesen
*/
if (quit!='n' && quit!=EOF)
while (test=getchar(),test!=EOF && test!='n');
}

return 0;
}

MfG
Horst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Horst Kraemer
Guest





PostPosted: Thu Nov 20, 2003 1:25 pm    Post subject: Re: Frage zu kleinem Programm Reply with quote

On Thu, 20 Nov 2003 10:53:16 +0100, Christoph Rabel
<odie (AT) hal9000 (DOT) vc-graz.ac.at> wrote:

Quote:
Daniel Brandelt wrote:
Hallo, ich bin c++ Anfänger und habe eine Frage zu dem unten aufgeführten
Programm.
Warum wird die Schleife immer 2 mal durchlaufen, wenn man in der Konsole
etwas anderes als "q"
eingibt ?

scanf( "%c", &quit );

Weil diese Zeile genau 1 Zeichen aus dem Buffer holt. Was du
vergisst, ist das im Tastaturbuffer auch noch das Enter
steht. Beim nächsten Schleifendurchlauf wird eben das Enter
aus dem Buffer geholt, in quit hineingeschrieben und erst
jetzt ist der Buffer leer.

Du musst also noch das Enter aus dem Buffer holen.

z.B. indem du die Zeile so änderst:

scanf( "%cn", &quit );

Hier versucht das scanf ein Zeichen und ein Enter zu parsen.

Nein. Das macht etwas voellig anderes. Nicht ausprobiert? Lies mal die
Dokumentation zu (f)scanf...

Im Formatstring sind alle Folgen von whitespace-Zeichen gleichwertig,
d.h.

scanf( "%cn", &quit );

ist in der Wirkung dasselbe wie

scanf( "%c t n ", &quit );

ist in der Wirkung dasselbe wie

scanf( "%c ", &quit );

Eine whitespace-Folge beliebiger Laenge bewirkt, dass scanf so lange
zu lesen versucht, bis es ein nicht-whitespace-Zeichen oder EOF sieht.
An der Konsole bedeutet das, dass Du nach der ersten mit x<RETURN>
abgeschlossenen Eingabe so lange Eingabeaufforderugen praesentiert
bekonnst, bis Du einmal etwas anderes als nur whitespace
(SPACE,TAB,RETURN) eingibst. Dieses erste nicht-whitespace-Zeichen,
das Du zwangsweise eingeben musst, um den ewigen Eingabeaufforderungen
des ersten scanf zu entrinnen, wird dann vom naechsten scanf *ohne*
neue Eingabeaufforderung gelesen. Ich glaube nicht, dass Du das willst
;-)

Der Formatstring fuer "ueberlies ein n" lautet

"%*1[n]"

Wenn Du sicher bist, dass der Anwender genau ein Zeichen vor dem
<RETURN> eingibt, ist aber

scanf( "%c%*c", &quit );

einfacher. (weise ein Zeichen an quit zu und wirf das naechste weg...)



Quote:
Das scheitert z.B. wenn du zwei Zeichen und ein Enter eingibst.

Richtig. Das bekommt man dann als scanf-Suechtiger mit

scanf( "%c%*[^n]", &quit );
scanf( "%*c" );

hin ;-)

Erstes Zeichen zuweisen, den Rest bis vor n (falls vorhanden)
wegwerfen und dann ein Zeichen weglesen. Alles auf einer Zeile a la

scanf( "%c%*[^n]%*c", &quit );

geht nicht, weil scanf bei %*[^n] wegen Misserfolgs (matching
failure) abbricht, wenn *kein* weiteres Zeichen vor dem n steht und
das n dann nicht wegliest. [ erwartet immer *mindestens* 1 Zeichen


Vermeide scanf wie die Pest, wenn Du nicht genau weisst, was es tut
;-)


MfG
Horst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Christoph Rabel
Guest





PostPosted: Thu Nov 20, 2003 1:55 pm    Post subject: Re: Frage zu kleinem Programm Reply with quote

Horst Kraemer wrote:
Quote:
On Thu, 20 Nov 2003 10:53:16 +0100, Christoph Rabel
[email]odie (AT) hal9000 (DOT) vc-graz.ac.at[/email]> wrote:
scanf( "%cn", &quit );

Hier versucht das scanf ein Zeichen und ein Enter zu parsen.

Nein. Das macht etwas voellig anderes. Nicht ausprobiert? Lies mal die
Dokumentation zu (f)scanf...

Nein, war zu faul.

Mir war zwar bewusst, dass die Lösung nur bedingt
funktioniert, aber diese Eigenschaft, dass alle
Whitespace-Zeichen gleichwertig sind, kannte ich nicht.

Ich habe früher immer fgets und sscanf verwendet, da hat man
ein paar Probleme weniger. Ist aber auch schon wieder eine
Weile her.

Quote:
Vermeide scanf wie die Pest, wenn Du nicht genau weisst, was es tut
Wink

Oh, das ist definitiv ein Ratschlag, an den ich mich halten
werde! ;-)

mfg

Christoph

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.