C: Clearing STDIN
grundsätzlich in codeblocks für windows vor jedem printf, ich habe "fflush(stdin);" funktioniert. Wenn ich kopiert mein code zu Linux, es funktioniert nicht, auch nicht eine der alternativen für die "fflush(stdin);", die ich gefunden habe. Egal wie ich scheinen, es zu tun, der Eingang scheint nicht zu klären, die in den Puffer oder so etwas in meinem code falsch ist.
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>
int main()
{
char pbuffer[10], qbuffer[10], kbuffer[10];
int p=0, q=0, k=0;
int r, i, Q, count, sum;
char a[3];
a[0]='y';
while(a[0]=='y' || a[0]=='Y')
{
printf("Enter a p value: \n");
fgets(pbuffer, sizeof(pbuffer), stdin);
p = strtol(pbuffer, (char **)NULL, 10);
printf("Enter a q value: \n");
fgets(qbuffer, sizeof(qbuffer), stdin);
q = strtol(qbuffer, (char **)NULL, 10);
printf("Enter a k value: \n");
fgets(kbuffer, sizeof(kbuffer), stdin);
k = strtol(kbuffer, (char **)NULL, 10);
while(p<q+1)
{
Q=p;
sum=0;
count=0;
while(Q>0)
{
count++;
r = Q%10;
sum = sum + pow(r,k);
Q = Q/10;
}
if ( p == sum && i>1 && count==k )
{
printf("%d\n",p);
}
p++;
a[0]='z';
}
while((a[0]!='y') && (a[0]='Y') && (a[0]!='n') && (a[0]!='N'))
{
printf("Would you like to run again? (y/n) ");
fgets(a, sizeof(a), stdin);
}
}
return 0;
}
- Sie werden, glaube ich Irrt. Gemäß Diesen Funktionen werden nicht standardisierte und nicht tragbar. Die Funktion fpurge() wurde in 4.4 BSD und nicht unter Linux verfügbar sind. Die Funktion __fpurge() wurde eingeführt, Solaris, und ist in glibc 2.1.95 und später. linux.die.net/man/3/fpurge
- Mit
a
definiert als einechar
Ihre Eingabe ist FALSCH (scanf(" %s", &a);
): es wird versuchen zu schreiben, zumindest die'\0'
Charakter in der memory-position nach, woa
liegt. Dass der Speicher position nicht zu dir gehören. - Sie mögen Recht haben - ich werde Sie löschen meinen Kommentar.
- Bitte beachten Sie, dass dieses Verhalten von
fflush
ist nicht, die allgemein unterstützt und nicht wirklich kompatibel mit der üblichen Bedeutung von "flush". Es gibt wirklich keinen standard, tragbare Weg zum löschen der Eingabe-Datenstrom, ohne zu Lesen von ihm. - BTW:
pow(r,k);
ist wahrscheinlich ein problem. Viele Beiträge SO auf, dass man. Verwenden Sie so etwas wieunsigned powuu(unsigned x, unsigned y) { unsigned z = 1u; unsigned base = x; while (y) { if (y & 1u) { z *= base; } y >>= 1u; base *= base; } return z; }
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aufrufen
fflush(stdin)
ist nicht standard, so ist das Verhalten undefiniert (siehe diese Antwort für weitere Informationen).Fordern, anstatt
fflush
aufstdin
zu nennen, könnten Siescanf
, vorbei an einem format-string und bündig die Funktion zu Lesen, alles bis zu und einschließlich der newline'\n'
Zeichen, wie diese:Das Sternchen zeigt
scanf
zu ignorieren das Ergebnis.Ein weiteres problem ist die Berufung
scanf
zu Lesen, ein Zeichen in der Variablena
mit dem Formatbezeichner der" %s"
: wenn der Benutzer ein nicht-leerer string, null-terminator schafft Pufferüberlauf verursacht Undefiniertes Verhalten (char a
ist ein Puffer von einem Zeichen; string"y"
hat zwei Zeichen -{'y', '\0'}
mit dem zweiten Zeichen geschrieben, über das Ende des Puffers). Sollten Siea
auf einen Puffer, der hat mehrere Zeichen, und übergeben Sie die Grenzescanf
:%s
im" %s"
sieht höchst verdächtig, auch.a
als Einzelzimmerchar
und verwenden" %c"
.scanf("%*[^\n]\n");
scannt nicht'\n'
, und wenn sich die Suche nach einem scan die Nummer white-space und wird nicht zurück, bis ein nicht-Leerzeichen eingegeben wird. Besserscanf("%*[^\n]%1*[\n]");
scanf(any_format, ...);
hat das problem, dass, wenn es keine Eingabe derzeit in den Eingabepuffer zu leeren,scanf()
wird nicht zurückkehren, bis es etwas. Diese erfüllen möglicherweise nicht die OP ' s braucht.Ich denke, was Sie versuchen zu tun, ist schwieriger als es scheint.
Meine interpretation von dem, was Sie zu tun versuchen ist zu deaktivieren, geben Sie im Voraus, so dass, wenn der Benutzer tippt einige Zeichen, während das Programm verarbeitet andere Sachen, Sie erscheinen nicht in der Eingabeaufforderung. Dies ist eigentlich ziemlich schwer zu tun, weil es ist ein OS-level-Funktion.
Könnten Sie tun, ein non-blocking read auf dem Gerät vor dem drucken die Aufforderung, bis man EWOULDBLOCK von errno. Oder die tcsetattr Funktion der Familie helfen könnte. Es sieht aus wie es ist ein Weg, um drain-Eingang für ein file-descriptor vorhanden, aber es könnte interagieren stark mit fgets/fscanf
Eine bessere Idee ist nicht zu befürchten, es überhaupt nicht. Unix-Benutzer sind gewohnt, geben Sie vor und was Sie wollen, wäre es zu unerwartetem Verhalten für Sie.
Drop die Notwendigkeit für die Spülung des eingabepuffers.
OP auf der rechten Spur mit
fgets()
eher alsscanf()
für den input, die OP sollte weiterhin, dass der Ansatz mit:Besten nicht zu verwenden
scanf()
als er versucht zu behandeln, Benutzer IO und Analyse in einem Schuss und nicht so gut.Bestimmte präsentieren OP die leiden stammen von
fgets()
nachscanf(" %s", &a);
(die UB, wie es sein solltescanf(" %c", &a);
. Mischenscanf()
mitfgets()
in der Regel hat das problem, dass diescanf(" %c", &a);
Blätter der Enter oder'\n'
im input-Puffer die Verpflichtung der code zu wollen flsuh der input-buffer vor dem nächstenfgets()
. Sonstfgets()
bekommt die veraltete'\n'
und nicht eine neue Zeile von info.Durch nur Verwendung
fgets()
für user-IO, Bedarf es für die Spülung wird negiert.Probe
fgets()
wrapperprintf("Would you like to run again? (y/n) \n"); if (fgets(buffer, 2, stdin) ...
wobuffer
ist zu klein. (Muss mindestens 3 sein.) Sonst ich würde haben, um zu sehen, deine korrigierte code. Sehen Sie, wenn der Puffer zu klein war, die'\n'
für diese Aufforderung ist immer noch im Eingabepuffer gelassen und am nächstenfgets()
nimmt, ohne zu warten, für eine andere Zeile der Eingabe - daher die 2 Aufforderungen "Geben Sie ein p-Wert" und "Geben Sie einen q-Wert:",'\n'
verzehrt werden sollten