Wie liest man mit C eine Zeichenfolge von der Tastatur?

Lesezeit: 6 Minuten

Benutzeravatar von mainajaved
Hauptsache

Ich möchte eine vom Benutzer eingegebene Zeichenfolge lesen. Die Länge der Saite kenne ich nicht. Da es keine Zeichenfolgen in CI gibt, wurde ein Zeiger deklariert:

char * word;

und verwendet scanf um Eingaben von der Tastatur zu lesen:

scanf("%s" , word) ;

aber ich habe einen Segmentierungsfehler.

Wie kann ich Eingaben von der Tastatur in C lesen, wenn die Länge unbekannt ist?

Benutzeravatar von Paul R
Paul R

Ihnen ist kein Speicherplatz zugewiesen word – Es ist nur ein baumelnder Zeiger.

Veränderung:

char * word;

zu:

char word[256];

Beachten Sie, dass 256 hier eine willkürliche Wahl ist – die Größe dieses Puffers muss größer sein als die größtmögliche Zeichenfolge, auf die Sie stoßen könnten.

Beachten Sie auch das fgets ist dann eine bessere (sicherere) Option Scanf zum Lesen von Zeichenfolgen beliebiger Länge, indem es a dauert size Argument, das wiederum hilft, Pufferüberläufe zu verhindern:

 fgets(word, sizeof(word), stdin);

  • -1: Er sagte, die Länge sei unbekannt und Ihre Wahl 256 ist völlig willkürlich, also haben Sie ihm gerade (naja, vor 2½ Jahren) beigebracht, wie man Pufferüberläufe und riesige Sicherheitslücken schreibt. Herzliche Glückwünsche.

    – Leichtigkeitsrennen im Orbit

    11. Juni 2014 um 17:19 Uhr


  • Vielen Dank für die (etwas verspätete) Kritik – ich habe die Antwort jetzt aktualisiert, um nicht nur den baumelnden Zeiger, sondern auch die Verwendungsempfehlung abzudecken fgets statt scanf für Zeichenfolgeneingabe beliebiger Länge.

    – PaulR

    12. Juni 2014 um 6:53 Uhr

  • Ah, wunderbar. 🙂 +1. Um fair zu sein, hat glglgl es verspätet gesagt, nur vierunddreißig Minuten nachdem Sie die Antwort gepostet haben! 😉

    – Leichtigkeitsrennen im Orbit

    12. Juni 2014 um 9:12 Uhr

Benutzeravatar von glglgl
glglgl

Ich kann nicht verstehen, warum es eine Empfehlung zur Verwendung gibt scanf() hier. scanf() ist nur dann sicher, wenn Sie der Formatzeichenfolge Einschränkungsparameter hinzufügen – wie z %64s oder so.

Ein viel besserer Weg ist die Verwendung char * fgets ( char * str, int num, FILE * stream );.

int main()
{
    char data[64];
    if (fgets(data, sizeof data, stdin)) {
        // input has worked, do something with data
    }
}

(ungetestet)

Benutzeravatar von David C. Rankin
David C. Rankin

Wenn Sie Eingaben aus einer beliebigen Datei (einschließlich stdin) lesen, bei der Sie die Länge nicht kennen, ist es oft besser, sie zu verwenden getline statt scanf oder fgets Weil getline wird die Speicherzuweisung für Ihren String automatisch handhaben, solange Sie einen Nullzeiger angeben, um den eingegebenen String zu erhalten. Dieses Beispiel soll Folgendes veranschaulichen:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) {

    char *line = NULL;  /* forces getline to allocate with malloc */
    size_t len = 0;     /* ignored when line = NULL */
    ssize_t read;

    printf ("\nEnter string below [ctrl + d] to quit\n");

    while ((read = getline(&line, &len, stdin)) != -1) {

        if (read > 0)
            printf ("\n  read %zd chars from stdin, allocated %zd bytes for line : %s\n", read, len, line);

        printf ("Enter string below [ctrl + d] to quit\n");
    }

    free (line);  /* free memory allocated by getline */

    return 0;
}

Die relevanten Teile sind:

char *line = NULL;  /* forces getline to allocate with malloc */
size_t len = 0;     /* ignored when line = NULL */
/* snip */
read = getline (&line, &len, stdin);

Einstellung line zu NULL bewirkt, dass getline automatisch Speicher zuweist. Beispielausgabe:

$ ./getline_example

Enter string below [ctrl + d] to quit
A short string to test getline!

  read 32 chars from stdin, allocated 120 bytes for line : A short string to test getline!

Enter string below [ctrl + d] to quit
A little bit longer string to show that getline will allocated again without resetting line = NULL

  read 99 chars from stdin, allocated 120 bytes for line : A little bit longer string to show that getline will allocated again without resetting line = NULL

Enter string below [ctrl + d] to quit

Also mit getline Sie müssen nicht erraten, wie lang die Zeichenfolge Ihres Benutzers sein wird.

  • Betreff fgets() v. getline(). Das grenzenlos getline(), ist IMO zu nah an einem Hacker-Exploit, da es ermöglicht, dass extern bereitgestellte Daten ein Programm überwältigen. Noch ein fester Puffer (fgets()) ist zu einschränkend. Ich habe damit gespielt, einen riesigen Puffer für zuzuweisen fgets() und sich auf *verzögerte Zuweisung zu verlassen, um Dinge zu kontrollieren.

    – chux – Wiedereinsetzung von Monica

    1. Mai 2015 um 18:35 Uhr

  • Richtig bist du. Als Lerche habe ich verwendet getline puffern 868789 Zeichenkette – keine Beschwerden. Ich werde mir Ihren Link mit verzögerter Zuweisung ansehen und sehen, welche Perlen/Gefahren dort liegen. Es gibt einfach keinen Ersatz für die Flexibilität getline bietet an. Ich habe mit dem Schreiben von Ersetzungen herumgebastelt fgetcaber Sie beenden das Umschreiben getline mehr oder weniger. Der Schutz im getline ist die Tatsache, dass es weiterhin zuweist und einen Überlauf verhindert, aber es liegt an Ihnen, die Größe des Ergebnisses auf Angemessenheit zu überprüfen …

    – David C. Rankin

    1. Mai 2015 um 21:49 Uhr

Benutzeravatar von Ananth Reddy
Ananth Reddy

#include<stdio.h>

int main()
{
    char str[100];
    scanf("%[^\n]s",str);
    printf("%s",str);
    return 0;
}

Eingabe: Lesen Sie die Zeichenfolge
Ausgabe: gibt den String aus

Dieser Code gibt die Zeichenfolge wie oben gezeigt mit Lücken aus.

Benutzeravatar von Juho
Juho

Sie müssen den Zeiger haben, um irgendwohin zu zeigen, um ihn zu verwenden.

Versuchen Sie diesen Code:

char word[64];
scanf("%s", word);

Dadurch wird ein Zeichenarray der Länge 64 erstellt und die Eingabe darin gelesen. Beachten Sie, dass, wenn die Eingabe länger als 64 Bytes ist, das Wortarray überläuft und Ihr Programm unzuverlässig wird.

Wie Jens betonte, wäre es besser, scanf nicht zum Lesen von Zeichenfolgen zu verwenden. Dies wäre eine sichere Lösung.

char word[64]
fgets(word, 63, stdin);
word[63] = 0;

  • Aus diesem Grund sollten Sie es nicht verwenden scanf an erster Stelle, um eine Zeichenfolge zu lesen; verwenden fgets stattdessen wird ein Längenargument verwendet.

    – Jens

    10. Oktober 2011 um 7:10 Uhr

  • @Jens: Du hast Recht und ich sollte mich schämen, zunächst keine bessere Lösung anzubieten. Ich habe meine Antwort bearbeitet, falls jemand kommt, um sie zu lesen.

    – Juho

    10. Oktober 2011 um 9:46 Uhr


  • fgets bereits Null beendet die Eingabezeichenfolge. Auch anders *scanfes berücksichtigt dies, so dass die Verwendung der vollen Größe des Arrays idiomatisch ist: fgets(word, sizeof word, stdin)

    – pmg

    10. Oktober 2011 um 11:40 Uhr


  • fgets(word, 63, stdin); word[63] = 0; –> fgets(word, sizeof word, stdin);

    – chux – Wiedereinsetzung von Monica

    1. Mai 2015 um 13:47 Uhr

Der folgende Code kann verwendet werden, um die Eingabezeichenfolge von einem Benutzer zu lesen. Aber der Platz ist auf 64 begrenzt.

char word[64] = { '\0' };  //initialize all elements with '\0'
int i = 0;
while ((word[i] != '\n')&& (i<64))
{
    scanf_s("%c", &word[i++], 1);
}

  • Aus diesem Grund sollten Sie es nicht verwenden scanf an erster Stelle, um eine Zeichenfolge zu lesen; verwenden fgets stattdessen wird ein Längenargument verwendet.

    – Jens

    10. Oktober 2011 um 7:10 Uhr

  • @Jens: Du hast Recht und ich sollte mich schämen, zunächst keine bessere Lösung anzubieten. Ich habe meine Antwort bearbeitet, falls jemand kommt, um sie zu lesen.

    – Juho

    10. Oktober 2011 um 9:46 Uhr


  • fgets bereits Null beendet die Eingabezeichenfolge. Auch anders *scanfes berücksichtigt dies, so dass die Verwendung der vollen Größe des Arrays idiomatisch ist: fgets(word, sizeof word, stdin)

    – pmg

    10. Oktober 2011 um 11:40 Uhr


  • fgets(word, 63, stdin); word[63] = 0; –> fgets(word, sizeof word, stdin);

    – chux – Wiedereinsetzung von Monica

    1. Mai 2015 um 13:47 Uhr

1414580cookie-checkWie liest man mit C eine Zeichenfolge von der Tastatur?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy