PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] fflush()?



ContainerDriver
29-08-2003, 15:22
Hi,
hab ein kleines Problem:
ich wollte mir ein eigenes getline() schreiben, nur leider bewirkt in der Funktion das fflush(stdin) irgendwie nichts!

Hier der Code:



#include <stdio.h>

int getline(char*target,int len)
{
int i;
int c=0;

for (i=0;i<=len && c!='\n';c=getchar(),target[i++]=c);

target[i-1]='\0'; //'\n' wird überschrieben

printf ("--->%s;", target);
fflush(stdin);
return i;
}

int main(void)
{
char buffer[10];
int buffer2;
getline(buffer,10);
printf("==%s",buffer);
scanf("%d",&buffer2);
return 0;
}


Wo liegt das Problem?

MfG

Florian

Edit by anda_skoa: sinnvolle Codeeinrückung :rolleyes:

ContainerDriver
29-08-2003, 15:23
Sehe grad, dass ich irendwas beim Code falsch gemacht habe, nochmal:

#include <stdio.h>
int getline(char*target,int len)
{
int i;
int c=0;
for (i=0;i<=len && c!='\n';c=getchar(),target[i++]=c);
target[i-1]='\0'; //'\n' wird überschrieben

printf ("--->%s;", target);

fflush(stdin);


return i;
}

int main(void)
{
char buffer[10];
int buffer2;

getline(buffer,10);

printf("==%s",buffer);

scanf("%d",&buffer2);

return 0;
}

wraith
29-08-2003, 15:29
fflush in Anwendung auf einen Inputstream ist undefiniert.
Wenn du den Inputstream leeren willst,dann mußt du das anders machen


#include <stdio.h>

void eatToNL(FILE * inputStream)
{
int c;
/* Eat till (& including) the next newline */
while ((c = getc(inputStream)) != EOF)
if (c == '\n')
break;
}

/* blah blah */
eatToNL(stdin);
/* blah blah */

ContainerDriver
29-08-2003, 15:31
Jo, werde ich mal probieren.
In dem C Buch wo hier rum liegt steht das mit dem flush(), geht ja ber nicht.

MfG

Florian

ContainerDriver
29-08-2003, 15:59
Hä? Ein erneuter Aufruf von getline (mit dem code von wraith open) funktioniert nicht (es wird nichts eingelesen)!!

cyneox
29-08-2003, 16:17
wärs eigentlich nicht besser wenn du eine while-scheleife benutzen würdest:



i=0;
while((c=getchar())!="\n" && i<=len)
target[++i]=c;

target[i-1]='\0';
printf("==>%s\n",target);
fflush(stdout);fflush(stdin);

return 1

wraith
29-08-2003, 16:17
Original geschrieben von florian hanisch
Hä? Ein erneuter Aufruf von getline (mit dem code von wraith open) funktioniert nicht (es wird nichts eingelesen)!!
Das ist so nicht korrekt ;).
Nein der 'Fehler' ist der,daß dein Code solange einliest bis der Buffer voll ist,oder ein EOF erkannt wurde,oder '\n' (das ist dann nicht mehr im Stream).
eatToNL warte aber auf ein '\n',wenn nichts im Stream ist,dann wartet er.

Mögliche Lösung,plus Korrektur deines off-by-one Errors.


void eatToNL(FILE * inputStream)
{
int c;
/* Eat till (& including) the next newline */
while ((c = getc(inputStream)) != EOF)
if (c == '\n')
break;
}

int getline(char *s,int lim)
{
int c,i;
for(i = 0;i < lim-1 && (c = getchar()) != EOF && c != '\n';++i)
s[i] = c;
if(c == '\n')
s[i] = c,++i;
else
eatToNL(stdin);
s[i] = '\0';
return i;
}

ContainerDriver
29-08-2003, 17:42
cyneox: ob for oder while schleife ist eigentlich egal
@ wraith: mmh, ich hab deinen code 1:1 übernommen, aber es läuft immer noch nicht (das selbe Prob)!

wraith
29-08-2003, 18:19
Original geschrieben von florian hanisch

@ wraith: mmh, ich hab deinen code 1:1 übernommen, aber es läuft immer noch nicht (das selbe Prob)!
Also ich hab' das jetzt auf drei Compilern getestet,und auf zweien lief es sofort wie erwartet,nur der MinGw Port machte wiedermal Zicken (wie so oft,das Ding ist zum Bugfixing gut,suckt sonst aber).

Naja,mit diesem Testcode läuft es so,wie ich denke das es laufen soll ;)


int main()
{
char buff[10];

getline(buff,10);
printf("%s\n",buff);
fflush(stdout);

getline(buff,10);
printf("%s\n",buff);
fflush(stdout);

getline(buff,10);
printf("%s\n",buff);
fflush(stdout);

return 0;
}

ContainerDriver
29-08-2003, 23:00
Hi wraith, also: dein Beispiel funktioniert, setzt man aber zwischen das getline() aber noch ein scanf zum einlesen von einer Zahl, wird das nächste getline() übersprungen (das ist das Problem). Man muss (weis Teufel warum) nach dem scanf noch ein eatToNL() setzten, dann funktioniert es.


MfG

FLorian

wraith
29-08-2003, 23:16
Original geschrieben von florian hanisch
setzt man aber zwischen das getline() aber noch ein scanf zum einlesen von einer Zahl, wird das nächste getline() übersprungen (das ist das Problem). Man muss (weis Teufel warum) nach dem scanf noch ein eatToNL() setzten, dann funktioniert es.

Ahja,auch das läßt sich leicht erklären.
Dein getline beendet das einlesen,sobald ein '\n' im Stream entdeckt wurde.
Aber ein scanf läßt das abschließende '\n' im Stream zurück,und die nachfolgende getline Anweisung liest genau dieses '\n' ein,und ist fertig.
Das ist immer das Problem,wenn man '\n' konsumierende Eingabefunktionen mit welchen mischt,die das '\n' im Stream lassen.
Es ist kein Problem mehrere scanfs hintereinander zu haben,weil das nächste scanf '\n' überliest.

ContainerDriver
30-08-2003, 11:59
Ahhh, verstehe!

Vielen Dank für deine Hilfe,
MfG

Florian

ActionNews
12-12-2003, 06:54
Ich habe das selbe Problem.

Eigentlich programmieren wir an der FH mit MS Visual C++ 6.0 aber ich möchte das zuhause gerne unter Linux proggen. Das Problem. Manchmal ist der Eingabepuffer nicht leer(aus einem vorherigen scanf), sodass ein weiteres scanf einfach übersprungen wird. Beim MS-Kompiler hilft ein einfaches fflush(stdin) nach jeden scanf, unter Linux leider nicht :(!

Was macht die Funktion eatToNL() denn eigentlich genau, dann könnte ich's damit versuchen.
Naja an der Uni funktioniert es ja mit fflush, aber zuhause kann ich das Program dann oft nicht testen.
Weiteres Problem: Die Funktionen müssen ANSI C konform sein (Bedingung der FH).

CU ActionNews

wraith
12-12-2003, 08:20
Original geschrieben von ActionNews
I
Weiteres Problem: Die Funktionen müssen ANSI C konform sein (Bedingung der FH).
Ja,das ist die Funktion eatoToNL.
Aber (wie bereits geschrieben),erzeugt fflush(stdin) undefiniertes Verhalten,also strenggenohmen nicht Ansi konform.

eatToNL liest alle Zeichen aus dem Inputbuffer aus (und schmeißt sie weg),bis zu einem Newline (welches auch weggeschmissen wird).

ActionNews
12-12-2003, 10:35
Ah ok, danke. Dann werde ich das zu Hause testen, wenn ich von der Uni wieder da bin :)!

CU ActionNews

ActionNews
12-12-2003, 16:15
Hmm... weder der Microsoft Visual C++ Kompiler noch gcc scheinen eatToNL (oder eatoToNL) zu kennen :(! Muss ich dafür erst eine bestimmte Bibliotek einbinden?
stdio.h, stdlib.h und string.h sind bereits eingebunden.

EDIT: Ach :o! *andenKopfklatsch*! Sorry für meine Schussligkeit, eatToNL ist ja eine Funktion die du oben selber deklariert hast !

CU ActionNews