Ich habe den folgenden Code geschrieben, um eine Zeile aus einem Terminalfenster zu lesen. Das Problem ist, dass der Code in einer Endlosschleife hängen bleibt. Die Zeile/der Satz hat eine undefinierte Länge, daher plane ich, sie in Teilen in den Puffer einzulesen und sie dann mit einer anderen Zeichenfolge zu verketten, die über erweitert werden kann realloc entsprechend. Kann bitte jemand meinen Fehler erkennen oder einen besseren Weg vorschlagen, dies zu erreichen?
Scheint ziemlich ok, wann soll die Schleife enden? So wie es jetzt ist, können Sie es beenden, indem Sie Strg + D auf * nix oder Strg + Z unter Windows drücken.
– Nr
12. Oktober 2010 um 21:08 Uhr
Ich sehe nichts offensichtlich Falsches am Code – wenn Sie “in einer Endlosschleife stecken” sagen, was meinen Sie genau?
– PaulR
12. Oktober 2010 um 21:09 Uhr
Benutzer411313
hier eine Verkettungslösung:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFERSIZE 10
int main() {
char *text = calloc(1,1), buffer[BUFFERSIZE];
printf("Enter a message: \n");
while( fgets(buffer, BUFFERSIZE , stdin) ) /* break with ^D or ^Z */
{
text = realloc( text, strlen(text)+1+strlen(buffer) );
if( !text ) ... /* error handling */
strcat( text, buffer ); /* note a '\n' is appended here everytime */
printf("%s\n", buffer);
}
printf("\ntext:\n%s",text);
return 0;
}
Warum zum +1 auf dieser Zeile: text = realloc( text, strlen(text)+1+strlen(buffer) ); ?
– Gonidelis
10. Januar 2019 um 13:23 Uhr
@johngonidelis eine Zeichenfolge wird als eine Reihe von ASCII-Werten der Zeichen gespeichert, mit einem einzelnen Zeichen am Ende mit dem Binärwert ‘0’. strlen() zählt nur die tatsächlichen Buchstaben, aber wenn Sie Platz für Ihren eigenen String anlegen, müssen Sie ein weiteres einzelnes Leerzeichen für das Nullbyte einfügen. Diese Zeile enthält die Anzahl der Zeichen, die bereits im Text enthalten sind, plus die Anzahl der Zeichen im Puffer, plus Platz für ein einzelnes Null-Byte, um das Ende der Zeichenfolge anzuzeigen.
Es gibt null zurück, wenn es ein EOF-Zeichen findet. Versuchen Sie, das obige Programm auszuführen und STRG+D zu drücken (oder welche Kombination auch immer Ihr EOF-Zeichen ist), und die Schleife wird erfolgreich beendet.
Wie möchten Sie das Ende der Eingabe erkennen? Neue Zeile? Dot (Du sagtest Satz xD)?
Das Ende der Eingabe sollte ein Zeilenumbruch sein
– robdavies35
12. Oktober 2010 um 21:19 Uhr
Scannen Sie Ihren Puffer nach Zeilenumbrüchen, dann 🙂
– sležica
12. Oktober 2010 um 21:21 Uhr
sapitando
Beendet die Schleife, wenn die Zeile leer ist (Verbesserungscode).
#include <stdio.h>
#include <string.h>
// The value BUFFERSIZE can be changed to customer's taste . Changes the
// size of the base array (string buffer )
#define BUFFERSIZE 10
int main(void)
{
char buffer[BUFFERSIZE];
char cChar;
printf("Enter a message: \n");
while(*(fgets(buffer, BUFFERSIZE, stdin)) != '\n')
{
// For concatenation
// fgets reads and adds '\n' in the string , replace '\n' by '\0' to
// remove the line break .
/* if(buffer[strlen(buffer) - 1] == '\n')
buffer[strlen(buffer) - 1] = '\0'; */
printf("%s", buffer);
// Corrects the error mentioned by Alain BECKER.
// Checks if the string buffer is full to check and prevent the
// next character read by fgets is '\n' .
if(strlen(buffer) == (BUFFERSIZE - 1) && (buffer[strlen(buffer) - 1] != '\n'))
{
// Prevents end of the line '\n' to be read in the first
// character (Loop Exit) in the next loop. Reads
// the next char in stdin buffer , if '\n' is read and removed, if
// different is returned to stdin
cChar = fgetc(stdin);
if(cChar != '\n')
ungetc(cChar, stdin);
// To print correctly if '\n' is removed.
else
printf("\n");
}
}
return 0;
}
Beenden, wenn die Eingabetaste gedrückt wird.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#define BUFFERSIZE 16
int main(void)
{
char buffer[BUFFERSIZE];
printf("Enter a message: \n");
while(true)
{
assert(fgets(buffer, BUFFERSIZE, stdin) != NULL);
// Verifies that the previous character to the last character in the
// buffer array is '\n' (The last character is '\0') if the
// character is '\n' leaves loop.
if(buffer[strlen(buffer) - 1] == '\n')
{
// fgets reads and adds '\n' in the string, replace '\n' by '\0' to
// remove the line break .
buffer[strlen(buffer) - 1] = '\0';
printf("%s", buffer);
break;
}
printf("%s", buffer);
}
return 0;
}
Verkettung und dynamische Zuordnung (verkettete Liste) zu einer einzelnen Zeichenfolge.
Liege ich falsch, oder wird die Schleife nur verlassen, wenn die leere Zeile direkt nach einer BUFFERSIZE-Grenze kommt?
– Alain Becker
12. September 2016 um 15:30 Uhr
@Alain BECKER Ich habe den Code verbessert (glaube ich), wirklich aus der Schleife in diesem Ereignis, aber jetzt verlässt er nur, wenn die Zeile leer ist (Drücken der Eingabetaste, ohne etwas einzugeben), ich habe mit TDM-GCC und LCC getestet.
– Sapitando
13. September 2016 um 17:39 Uhr
Es macht wirklich nicht viel Sinn, (a) eine Wand mit Code (b) ohne Erklärung zu (c) einer 6 Jahre alten Frage zu posten, die (d) bereits gute Antworten hat.
– PaulR
14. September 2016 um 6:12 Uhr
@ Paul R Wenn Sie den Code ausführen, werden Sie sehen, dass er selbsterklärend ist und keine Antwort zufriedenstellend ist (Schleife mit Ctrl + Z verlassen) oder so, und ich bin Neuling darin, ich habe diese Frage als Übungsweg verwendet.
– Sapitando
14. September 2016 um 6:30 Uhr
Steve Emmerson
Angenommen, Sie möchten nur eine einzige Zeile lesen, dann verwenden Sie LINE_MAXdie in definiert ist <limits.h>:
Wenn Sie die Eingabe verketten möchten, ersetzen Sie sie printf("%s\n", buffer); mit strcat(big_buffer, buffer);. Erstellen und initialisieren Sie auch den großen Puffer am Anfang: char *big_buffer = new char[BIG_BUFFERSIZE];big_buffer[0] = '\0';. Sie sollten auch einen Pufferüberlauf verhindern, indem Sie überprüfen, ob die aktuelle Pufferlänge plus die neue Pufferlänge das Limit nicht überschreiten: if ((strlen(big_buffer) + strlen(buffer)) < BIG_BUFFERSIZE). Das modifizierte Programm würde wie folgt aussehen:
Scheint ziemlich ok, wann soll die Schleife enden? So wie es jetzt ist, können Sie es beenden, indem Sie Strg + D auf * nix oder Strg + Z unter Windows drücken.
– Nr
12. Oktober 2010 um 21:08 Uhr
Ich sehe nichts offensichtlich Falsches am Code – wenn Sie “in einer Endlosschleife stecken” sagen, was meinen Sie genau?
– PaulR
12. Oktober 2010 um 21:09 Uhr