Frage

Ich schreibe ein Programm, das angeblich zwei Strings zu lesen, die Zeilenumbrüche und verschiedene andere Zeichen enthalten. Daher verwende ich EOF (Strg-Z oder Strg-D), um die Zeichenfolge zu beenden.

Dies funktioniert mit der ersten Größe, aber mit den zweiten Variablen, jedoch scheint dies problematisch zu sein, da offenbar etwas in den Eingangspuffern stecken, und der Benutzer erhält nicht in irgendetwas zu geben.

Ich habe versucht, den Puffer mit while (getchar() != '\n'); und mehr ähnlichen Variationen zu reinigen, aber nichts scheint zu helfen. Alle Reinigungsversuche wurden in einer Endlos-Schleife geführt und ohne Reinigung, die zweite Variable Zugabe unmöglich ist.

Die Zeichen für beide der Variablen in einer Schleife wie folgt lesen: while((c = getchar()) != EOF), was würde vorschlagen, es ist EOF, was ich in meinem Puffer stecken haben. Oder ist es das Verhalten des Programms auf andere Weise beeinflussen? Gibt es etwas falsch mit der Logik ich verwende?

Ich fange bisschen verzweifelt zu erhalten, nachdem mit diesem stundenlang zu kämpfen.

[edit: hinzugefügt Code unten]

[Bearbeiten. 2: clearerr () scheint diese EOF-Lösung arbeiten, nachdem alle zu machen

Es scheint, in seiner ursprünglichen Form zu laufen, wie ich unter Linux gedacht, ich war es mit dem Windows gestern versucht.]

code:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int x = 0;
    int c;
    char a[100];
    char b[100];

    printf("Enter a: ");
    while((c = getchar()) != EOF)
    {
        a[x] = c;
        x++;
    }
    a[x] = '\0';
    x = 0;

    /*while (getchar() != '\n'); - the non-working loop*/

    printf("\nEnter b: ");
    while((c = getchar()) != EOF)
    {
        b[x] = c;
        x++;
    }
    b[x] = '\0';

    printf("\n\nResults:\na: %s\n", a);
    printf("b: %s\n", b);

    return(0);
}

[Bearbeiten 3:]

Dynamische Speicherproblem:

Mein Programm soll auch länger als 100 Zeichen Zeichenfolge behandeln. Ursprünglich wollte ich, dass durch die dynamische Speicherzuweisung lösen, aber wenn ich Probleme mit der Endlos-Schleife oben und speicherbezogene Abstürzen beschrieben hatte ließ ich es aus und umgeschaltet auf char [100].

Ich denke, was ich versuchte, war in der Regel so etwas wie folgt aus:

while((c = getchar()) != EOF)
{
  a = malloc(sizeof(char));
  a[x] = c;
  x++;
}

Ist das ein möglicher (oder sinnvoll) Weg, dies zu tun? Ich versuche, mehr Speicher für jedes Zeichen zuzuordnen, die dort behandelt haben werden. Individuell. Mit Code wie die (in diesem Beispiel enthält wahrscheinlich Syntaxfehler) Ich Abstürze erlebt, so sieht für mich vielleicht malloc nicht die richtige Funktion hier sein, oder ich versuche es falsch. Angenommen, es ist sogar möglich.

War es hilfreich?

Lösung

Nachdem Sie einen EOF vom Endgerät empfangen, Sie werden keine zusätzlichen Daten erhalten. Es gibt keine Möglichkeit, un-EOF-ing den Eingang - das Ende der Datei ist, na ja, das Ende

.

So definieren Sie sollten, dass jede Variable Eingang in einer separaten Zeile ist, und haben die Benutzer drücken statt EOF eingeben. Sie müssen noch prüfen, ob Sie EOF empfangen haben, weil das bedeutet, dass der Benutzer tatsächlich EOF eingegeben haben, und Sie werden nichts anderes sehen -. In diesem Fall Sie aus der Schleife brechen müssen und eine Fehlermeldung

Andere Tipps

EOF ist kein Charakter - es ist ein besonderer Wert, dass die Eingangsfunktionen geben einen Zustand anzuzeigen , dass das „Ende der Datei“ an diesem Eingangsstrom hat erreicht ist. Wie Martin v. Löwis sagt einmal: „Ende der Datei“ auftritt, bedeutet dies, dass nicht mehr Eingang auf diesem Strom zur Verfügung stehen wird.

Die Verwirrung entsteht, weil:

  • Viele Terminaltypen erkennen einen speziellen Tastendruck „Ende der Datei“ zu signalisieren, wenn die „Datei“ ist ein interaktives Terminal (zB Strg-Z oder Strg-D.); und
  • Der EOF Wert ist einer der Werte, die von der getchar() Familie von Funktionen zurückgegeben werden können.

Sie müssen einen tatsächlichen Zeichenwert verwenden, um die Eingänge zu trennen. - Das ASCII-Zeichen NUL '\0' könnte eine gute Wahl sein, wenn das nicht als gültigen Wert innerhalb der Eingänge selbst erscheint

ich den Code auf meinem Linux-Box laufen, hier ist das Ergebnis:

Enter a: qwer
asdf<Ctrl-D><Ctrl-D>
Enter b: 123
456<Ctrl-D><Ctrl-D>

Results:
a: qwer
asdf
b: 123
456

Zwei Ctrl-D benötigt wurden, da die Terminal-Eingangspuffer nicht leer waren.

Sie könnten die Null-Zeichen ('\0') verwenden, um die Variablen zu trennen. Verschiedene UNIX-Tools (z find) sind in der Lage, ihre Ausgabeelemente auf diese Weise zu trennen, was würde vorschlagen, dass es eine ziemlich Standard-Methode ist.

Ein weiterer Vorteil ist, dass man den Strom in einen einzigen Puffer lesen kann und dann eine Reihe von char*s erstellen, um die einzelnen Strings zu zeigen und jede Saite richtig '\0'-beendet wird, ohne dass Sie etwas im Puffer ändern manuell. Dies bedeutet weniger Speicherzuweisung Overhead, die Ihr Programm deutlich schneller laufen lassen können, je nachdem, wie viele Variablen, die Sie gerade lesen. Natürlich ist dies nur erforderlich, wenn Sie alle Variablen im Speicher zur gleichen Zeit halten, müssen - wenn Sie mit ihnen ein-at-a-time zu tun haben, müssen Sie nicht diesen besonderen Vorteil erhalten

.

Was Sie versuchen, ist im Grunde unmöglich, mit EOF.

Obwohl es wie ein in gewisser Weise verhält, ist EOF kein Charakter in dem Strom, sondern ein Umfeld definiertes Makro, die das Ende des Stroms. Ich habe nicht den Code gesehen, aber ich sammeln Sie tun, ist so etwas wie folgt aus:

while ((c=getchar()) != EOF) {
    // do something
}
while ((c=getchar()) != EOF) {
    // do something else
}

Wenn Sie das EOF-Zeichen das erste Mal eingeben, den ersten String zu beenden, wird der Strom unwiderruflich geschlossen. Das heißt, der Status des Stroms ist, dass es geschlossen ist.

So wird der Inhalt der zweiten while-Schleife nie ausgeführt werden.

Anstatt zu stoppen Lesen Eingang bei EOF - , das kein Zeichen ist - bei ENTER stoppen

.
while((c = getchar()) != '\n')
{
    if (c == EOF) /* oops, something wrong, input terminated too soon! */;
    a[x] = c;
    x++;
}

EOF ist ein Signal, dass die Eingabe beendet. Sie sind fast garantiert, dass alle Eingaben vom Benutzer mit ‚\ n‘ Ende: das ist der letzte Schlüssel der Benutzer !!!


Edit: Sie können immer noch mit Strg-D und clearerr() des Eingangsstroms zum Zurücksetzen

.
#include <stdio.h>

int main(void) {
  char a[100], b[100];
  int c, k;

  printf("Enter a: "); fflush(stdout);
  k = 0;
  while ((k < 100) && ((c = getchar()) != EOF)) {
    a[k++] = c;
  }
  a[k] = 0;

  clearerr(stdin);

  printf("Enter b: "); fflush(stdout);
  k = 0;
  while ((k < 100) && ((c = getchar()) != EOF)) {
    b[k++] = c;
  }
  b[k] = 0;

  printf("a is [%s]; b is [%s]\n", a, b);
  return 0;
}
$ ./a.out
Enter a: two
lines (Ctrl+D right after the next ENTER)
Enter b: three
lines
now (ENTER + Ctrl+D)
a is [two
lines (Ctrl+D right after the next ENTER)
]; b is [three
lines
now (ENTER + Ctrl+D)
]
$
  

Wie Sie im Programm null eingeben?

Sie können implementieren die -print0 Funktion:

putchar(0);

Dies wird ein ASCII-NUL-Zeichen '\ 0' sdtout drucken.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top