stdin puffer

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
GnuRip
Beiträge: 8
Registriert: Do Jul 23, 2015 1:32 pm

stdin puffer

Beitrag von GnuRip » Do Aug 06, 2015 11:37 am

Erstmal zum Vorwissen: Ich fange gerade ganz frisch mit C an, habe aber gute Kenntnisse in Java. Mehr dazu im Vorstellungsthread.

Ich habe jetzt erstmal nicht mit dem Tutorial von proggen.org angefangen, sondern mit dem Openbook "C von A bis Z".

Dort wird anfangs auf das Problem des stdin puffers bei Konsoleneingaben eingegangen.
http://openbook.rheinwerk-verlag.de/c_v ... 5efcc47322

Deren beispiel "scanf2.c" verhält sich so wie dort auch angegeben. Möglichkeit 1 mit fflush verhält sich genauso wie das erste Beispiel, Möglichkeit 2 funktioniert wie es soll (ich kann also 3 Buchstaben eingeben und ausgeben lassen). Aber der Knackpunkt ist Möglichkeit 3 die wohl die beste Variante (weil verzicht auf scanf) sein soll.

Deren Code sieht so aus:

Code: Alles auswählen

/* scanf5.c */
#include <stdio.h>

int main(void) {
   char ch;
   char buf[2];

   printf("Ein Zeichen bitte : ");
   fgets(buf, 2, stdin);
   sscanf(buf, "%c", &ch);
   printf("Das Zeichen : %c\n",ch);
   return 0;
}
Das ist leider ziemlich witzlos, wenn nur ein Zeichen eingegeben werden soll funktionieren die anderen Beispiele ja auch. Also habe ich das erweitert zu:

Code: Alles auswählen

#include <stdio.h>

int main(void) {
char ch;
char buf[2];

char ch2;
char buf2[2];

printf("Zeichen 1: ");
fgets(buf, 2, stdin);
sscanf(buf, "%c", &ch);

printf("Zeichen 2: ");
fgets(buf2, 2, stdin);
sscanf(buf2, "%c", &ch2);

printf("Die Zeichen : %c %c\n", ch, ch2);

return 0;                                                                                                                                                                                                                              
}  

Das sieht dann bei mir so aus:
Zeichen 1: a
Zeichen 2: Die Zeichen : a
Es verhält sich also genauso wie das original Beispiel und Möglichkeit 1. Was mache ich nun falsch?

Getestet habe ich das unter OS X 10.10.4
Compiler:
gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
und alternativ:
gcc-5 --version
gcc-5 (Homebrew gcc 5.2.0 --with-all-languages) 5.2.0
Copyright (C) 2015 Free Software Foundation, Inc.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: stdin puffer

Beitrag von mfro » Do Aug 06, 2015 1:41 pm

Erstmal: fflush(stdin) ist undefiniert, das steht explizit so im Standard.
Undefiniertes Verhalten darf laut Standard alles x-beliebige machen (z.B. deine Festplatte löschen oder deine Kreditkartendaten nach Russland schicken). Linux glibc macht das in dieser Situation Ungefährlichste: nix.

Dann zu deinem Beispiel: scanf() liest solange Zeichen ein, bis entweder der Puffer voll ist oder ein Newline ankam. Das Newline wird mit in den Puffer geschrieben, ebenso wie ein Nullbyte am Ende.

Wenn Du also eine einzelne Ziffer (z.B. "5") einliest, steht in deinem Puffer: { '5', '\n', '\0' }. Das sind drei Zeichen. Du hast deinen Puffer aber nur zwei Zeichen lang gemacht (so daß er schon nach einem einzelnen Zeichen voll ist, weil das Nullbyte ja noch rein muß), also steht bei dir { '5', '\0' } und das Newline steckt noch im Eingabepuffer und ist deinem nächsten scanf() im Weg.

Mach' einfach deine Eingabepuffer ein Element größer (3) und die fgets()-Maximallänge entsprechend. Schon funktioniert's.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

GnuRip
Beiträge: 8
Registriert: Do Jul 23, 2015 1:32 pm

Re: stdin puffer

Beitrag von GnuRip » Fr Aug 07, 2015 2:26 pm

Ah das funktioniert.
Was mich jetzt aber wundert, ist das jetzt ein grober Fehler in dem Buch "C von A bis Z" oder ist das System abhängig? Dort schreiben die ja auch von dem Puffer, und dass das Newline im Puffer steckt, aber das Nullbyte wird an der Stelle nicht erwähnt.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: stdin puffer

Beitrag von mfro » Fr Aug 07, 2015 5:42 pm

Tja, es gibt halt bessere und schlechtere Bücher ;)
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Antworten