Wie kann ich eine Eingabezeichenfolge unbekannter Länge lesen?

Wenn ich nicht weiß, wie lange das Wort ist, kann ich nicht char m[6]; schreiben char m[6]; ,
Die Länge des Wortes ist vielleicht zehn oder zwanzig. Wie kann ich scanf , um Eingaben von der Tastatur zu erhalten?

 #include  int main(void) { char m[6]; printf("please input a string with length=5\n"); scanf("%s",&m); printf("this is the string: %s\n", m); return 0; } 

Bitte geben Sie eine Zeichenfolge mit Länge = 5 ein
Hallo
Das ist die Zeichenfolge: Hallo

Geben Sie ein, während Sie einen Bereich dynamisch sichern

Z.B

 #include  #include  char *inputString(FILE* fp, size_t size){ //The size is extended by the input with the value of the provisional char *str; int ch; size_t len = 0; str = realloc(NULL, sizeof(char)*size);//size is start size if(!str)return str; while(EOF!=(ch=fgetc(fp)) && ch != '\n'){ str[len++]=ch; if(len==size){ str = realloc(str, sizeof(char)*(size+=16)); if(!str)return str; } } str[len++]='\0'; return realloc(str, sizeof(char)*len); } int main(void){ char *m; printf("input string : "); m = inputString(stdin, 10); printf("%s\n", m); free(m); return 0; } 

Mit den heutigen Computern können Sie sehr große Strings (Hunderttausende von Zeichen) zuweisen, ohne den RAM-Verbrauch des Computers zu beeinträchtigen. Also würde ich mir nicht zu viele Sorgen machen.

In den alten Zeiten, in denen Speicher eine große Rolle spielte, war es üblich, Strings in Blöcken zu lesen. fgets liest bis zu einer maximalen Anzahl von Zeichen aus der Eingabe, lässt aber den Rest des Eingabepuffers intakt, so dass Sie den Rest davon lesen können, wie Sie möchten.

In diesem Beispiel lese ich Teile von 200 Zeichen, aber Sie können natürlich auch die gewünschte Größe verwenden.

 #include  #include  #include  char* readinput() { #define CHUNK 200 char* input = NULL; char tempbuf[CHUNK]; size_t inputlen = 0, templen = 0; do { fgets(tempbuf, CHUNK, stdin); templen = strlen(tempbuf); inputlen += templen; input = realloc(input, inputlen+1); strcat(input, tempbuf); } while (templen==CHUNK-1 && tempbuf[CHUNK-2]!='\n'); return input; } int main() { char* result = readinput(); printf("And the result is [%s]\n", result); free(result); return 0; } 

Beachten Sie, dass dies ein vereinfachtes Beispiel ohne Fehlerprüfung ist. Im wirklichen Leben müssen Sie sicherstellen, dass die Eingabe in Ordnung ist, indem Sie den Rückgabewert von fgets .

Beachten Sie auch, dass am Ende, wenn die Readinput-Routine, keine Bytes verschwendet werden; Die Zeichenfolge hat die genaue Speichergröße, die sie haben muss.

Ich habe nur eine einfache Möglichkeit gesehen, eine beliebig lange Zeichenfolge zu lesen, aber ich habe sie nie benutzt. Ich denke es geht so:

 char *m = NULL; printf("please input a string\n"); scanf("%ms",&m); if (m == NULL) fprintf(stderr, "That string was too long!\n"); else { printf("this is the string %s\n",m); /* ... any other use of m */ free(m); } 

Das m zwischen % und s teilt scanf() mit, um die Zeichenfolge zu messen und ihr Speicher zuzuordnen, die Zeichenfolge in diese zu kopieren und die Adresse des zugeordneten Speichers im entsprechenden Argument zu speichern. Sobald Sie damit fertig sind, müssen Sie es free() .

Dies wird jedoch nicht bei jeder Implementierung von scanf() unterstützt.

Wie andere hingewiesen haben, ist die einfachste Lösung, die Länge der Eingabe zu begrenzen. Wenn Sie scanf() weiterhin verwenden möchten, können Sie dies folgendermaßen tun:

 char m[100]; scanf("%99s",&m); 

Beachten Sie, dass die Größe von m[] mindestens ein Byte größer als die Zahl zwischen % und s .

Wenn die eingegebene Zeichenfolge länger als 99 ist, warten die verbleibenden Zeichen darauf, von einem anderen Aufruf oder vom Rest der an scanf() übergebenen scanf() gelesen zu werden.

Im Allgemeinen wird scanf() nicht zur Verarbeitung von Benutzereingaben empfohlen. Es eignet sich am besten für strukturierte Textdateien, die von einer anderen Anwendung erstellt wurden. Selbst dann müssen Sie sich darüber im Klaren sein, dass die Eingabe möglicherweise nicht wie erwartet formatiert wurde, da sich jemand daran beteiligt haben könnte, um Ihr Programm zu unterbrechen.

Wenn ich einen sichereren Ansatz vorschlagen könnte:

Deklarieren Sie einen Puffer, der groß genug ist, um die Zeichenfolge aufzunehmen:

char user_input[255];

Holen Sie sich die Benutzereingaben auf sichere Weise:

fgets(user_input, 255, stdin);

Ein sicherer Weg, die Eingabe zu erhalten, wobei das erste Argument ein pointers auf einen Puffer ist, in dem die Eingabe gespeichert wird, der zweite die maximale Eingabe, die die function lesen sollte, und die dritte ein pointers auf die Standardeingabe – dh wo die Benutzereingabe kommt von.

Sicherheit kommt insbesondere von dem zweiten Argument, das einschränkt, wieviel gelesen wird, was Pufferüberläufe verhindert. Außerdem fgets dafür, dass die verarbeitete Zeichenfolge auf Null gesetzt wird.

Weitere Informationen zu dieser function finden Sie hier .

BEARBEITEN: Wenn Sie eine Formatierung vornehmen müssen (z. B. eine Zeichenfolge in eine Zahl konvertieren), können Sie atoi verwenden, sobald Sie die Eingabe haben.

Sicherer und schneller (doppelte Kapazität) Version:

 char *readline(char *prompt) { size_t size = 80; char *str = malloc(sizeof(char) * size); int c; size_t len = 0; printf("%s", prompt); while (EOF != (c = getchar()) && c != '\r' && c != '\n') { str[len++] = c; if(len == size) str = realloc(str, sizeof(char) * (size *= 2)); } str[len++]='\0'; return realloc(str, sizeof(char) * len); } 

Nehmen Sie einen Zeichenzeiger, um die erforderliche Zeichenfolge zu speichern. Wenn Sie eine Idee über die mögliche Größe der Zeichenfolge haben, verwenden Sie die function

 char *fgets (char *str, int size, FILE* file);` 

Ansonsten können Sie Speicher auch zur Laufzeit zuweisen, indem Sie die function malloc () verwenden, die dynamisch angeforderten Speicher bereitstellt.

Ich weiß, dass ich nach 4 Jahren angekommen bin und zu spät bin, aber ich denke, ich habe einen anderen Weg, den jemand benutzen kann. Ich hatte getchar() function wie getchar() verwendet: –

 #include  #include  #include  //I had putten the main Function Bellow this function. //d for asking string,f is pointer to the string pointer void GetStr(char *d,char **f) { printf("%s",d); for(int i =0;1;i++) { if(i)//Ie if i!=0 *f = (char*)realloc((*f),i+1); else *f = (char*)malloc(i+1); (*f)[i]=getchar(); if((*f)[i] == '\n') { (*f)[i]= '\0'; break; } } } int main() { char *s =NULL; GetStr("Enter the String:- ",&s); printf("Your String:- %s \nAnd It's length:- %lu\n",s,(strlen(s))); free(s); } 

Hier ist der Beispiellauf für dieses Programm:

 Enter the String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!! Your String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!! And It's length:- 67 

Mit fgets() direkt in den zugewiesenen Platz fgets() .

Besondere Sorgfalt ist erforderlich, um ein erfolgreiches Lesen, Dateiende, Eingabeerrors und nicht genügend Arbeitsspeicher zu unterscheiden. An EOF wird eine korrekte Speicherverwaltung benötigt.

Diese Methode behält eine Zeile '\n' .

 #include  #include  #define FGETS_ALLOC_N 128 char* fgets_alloc(FILE *istream) { char* buf = NULL; size_t size = 0; size_t used = 0; do { size += FGETS_ALLOC_N; char *buf_new = realloc(buf, size); if (buf_new == NULL) { // Out-of-memory free(buf); return NULL; } buf = buf_new; if (fgets(&buf[used], (int) (size - used), istream) == NULL) { // feof or ferror if (used == 0 || ferror(istream)) { free(buf); buf = NULL; } return buf; } size_t length = strlen(&buf[used]); if (length + 1 != size - used) break; used += length; } while (buf[used - 1] != '\n'); return buf; } 

Beispielnutzung

 int main(void) { FILE *istream = stdin; char *s; while ((s = fgets_alloc(istream)) != NULL) { printf("'%s'", s); free(s); fflush(stdout); } if (ferror(istream)) { puts("Input error"); } else if (feof(istream)) { puts("End of file"); } else { puts("Out of memory"); } return 0; } 

Ich habe auch eine Lösung mit Standard-Ein- und -Ausgängen

 #include #include int main() { char *str,ch; int size=10,len=0; str=realloc(NULL,sizeof(char)*size); if(!str)return str; while(EOF!=scanf("%c",&ch) && ch!="\n") { str[len++]=ch; if(len==size) { str = realloc(str,sizeof(char)*(size+=10)); if(!str)return str; } } str[len++]='\0'; printf("%s\n",str); free(str); }