Lesen Sie nicht mehr als die Größe des Strings mit scanf()

Lesezeit: 4 Minuten

[*]
MrHappyAsthma

Bearbeiten: Für meine Klasse muss ich verwenden scanf. Das Empfehlen anderer Eingabemöglichkeiten ist also nicht die Lösung, nach der ich suche (falls es eine gibt, die scanf beinhaltet).


Wenn ich Benutzereingaben für ein kleines Projekt (z. B. ein Spiel) einlese. Nehmen wir an, ich frage would you like to play? Dies würde eine akzeptieren yes oder no Antworten. Also schreibe ich einen einfachen Code wie diesen:

#include <stdio.h>

int main(void)
{
     char string[3]; //The max number of letters for "yes".

     printf("Would you like to play?");
     scanf("%s", string);
}

Dieser Code sollte sie also einfach zur Eingabe auffordern yes oder no. Ich stelle die Länge meiner ein char array messen 3. Auf diese Weise ist es groß genug, um es zu halten yes und auch no. Aber wenn jemand ungültige Eingaben wie z yesss, ich weiß, wie man die Zeichenfolge danach vergleicht, um ein solches Ereignis zu behandeln, aber würde dies nicht technisch/möglicherweise andere lokale Variablen überschreiben, die ich deklariert habe, weil es die Länge meines Arrays überschreiten würde? Wenn ja, gibt es eine Möglichkeit, damit umzugehen, um 3 Eingabezeichen oder so etwas einzuschränken? Und wenn nicht, warum/woher weiß es, dass nur die Größe 3 eingegeben werden soll?

  • Wahrscheinlich sicherer, es Zeichen für Zeichen zu tun. Ich bin mir nicht sicher, ob C irgendetwas hat, das dies für Sie erledigt.

    – Chris

    6. September 2012 um 18:55 Uhr

  • Können Sie erklären, wie das geht? Würde ich einfach ein paar “%c”-Sachen in “scanf” machen und wie würde ich sie dann einem Zeichen des Arrays zuweisen? [i.e. would I need &string[0] oder so]. Und wenn sie “nein” eingeben, würde ich nur 2 der 3 “%c” verwenden.

    – MrHappyAsthma

    6. September 2012 um 18:57 Uhr

  • Wenn Sie es selbst tun, um eine beliebige Länge zu handhaben, müssen Sie ein Array erstellen, dessen Größe sich zur Laufzeit ändern kann, und Zeichen aus der Eingabe einfügen, sobald sie kommen, während Sie sicherstellen, dass das Array nicht überläuft. Zum Glück, so scheint es scanf hat die Funktion eingebaut.

    – Chris

    6. September 2012 um 18:59 Uhr

Ihr Array muss in der Lage sein, vier zu halten chars, da es auch den 0-Terminator enthalten muss. Wenn dies behoben ist und eine maximale Länge im Format angegeben wird,

scanf("%3s", string);

versichert dass scanf liest nicht mehr als 3 Zeichen.

  • Nebenbei bemerkt, da der Breitenbezeichner nur die anzeigt maximal Anzahl der zu lesenden Zeichen, wenn Sie eine lesen müssen genau verwenden Sie den obigen Ansatz und überprüfen Sie dann die Anzahl der verbrauchten Zeichen (via %n).

    – Sevko

    10. Juli 2015 um 18:18 Uhr

  • Ich möchte nur wissen, dass dies eine super tolle Sache ist. Warum sagen die Leute dann immer wieder, dass scanf unsicher ist, offensichtlich könnten sie dies tun, um die Eingabe zu begrenzen und den Pufferüberlauf-Exploit zu stoppen. ??

    – Suraj Jain

    11. April 2017 um 4:53 Uhr

  • “stellt sicher, dass scanf nicht mehr als 3 Zeichen liest.” –> Nicht ganz. "%3s" liest zunächst eine unbegrenzte Anzahl führender Leerzeichen. Dann werden bis zu 3 Nicht-Leerzeichen gelesen und gespeichert. Schließlich das Anhängen von a Nullzeichen.

    – chux – Wiedereinsetzung von Monica

    23. September 2018 um 23:28 Uhr


  • @SurajJain Die Leute raten im Allgemeinen von Scanf ab, nicht weil es nicht sicher verwendet werden kann, sondern weil es schwierig zu verwenden ist. Wenn Leute zum ersten Mal C lernen, wäre es besser, wenn sie lernen, Eingabezeichenfolgen zu parsen, als Zeit damit zu verbringen, die Schwächen der Scanf-Formatsprache zu lernen. scanf wird selten im Produktionscode verwendet; an den allermeisten Stellen mag es angebracht sein, C ist sowieso die falsche Sprache.

    – William Pursel

    5. Mai 2019 um 13:59 Uhr

Benutzeravatar von Timothy Malche
Timotheus Malche

Der sicherste Weg ist die Verwendung

fgets(string, 4, stdin);

Hier können Sie maximal 3 Zeichen speichern, einschließlich eines reservierten Leerzeichens NULL ('\0') Charakter.

  • Exakt! Der beste (und innovativste) Weg, tbh! Vielen Dank

    – Mrigank Pawagi

    8. Juni 2018 um 15:09 Uhr

  • Üblicherweise wird das letzte der „maximal 3 Zeichen“ gelesen '\n'.

    – chux – Wiedereinsetzung von Monica

    23. September 2018 um 23:30 Uhr

  • fgets() liest beliebige Zeichen (einschließlich Leerzeichen) bis EOF oder \n. Es ist also keine Alternative zu scanf(), das sich um das Format des gelesenen Strings kümmert.

    – derschüddi

    5. Oktober 2021 um 10:17 Uhr

Benutzeravatar von gsamaras
Gsamaras

Sie sollten die verwenden Breite Modifikator von scanf() und stelle es ein einer weniger als die Größe Ihrer Zeichenfolge, damit Sie sicherstellen, dass Platz für die vorhanden ist NULL Terminator.

Wenn Sie also “Ja” speichern möchten, benötigen Sie zunächst ein größeres Array als das, das Sie haben. eine mit Größe 4, 3 Zeichen plus 1 für das Null-Terminator. Außerdem sollten Sie belehren scanf() nicht mehr lesen als Größe – 1 Zeichen, wobei Größe die Länge Ihres Arrays ist, also in diesem Fall 3, wie folgt:

#include <stdio.h>

int main(void)
{
     char string[4];
     scanf("%3s", string);
}

  • Das wird nach einer Ziffer suchen 3… stattdessen verwenden "%3s"

    – Jonathan Lidbeck

    28. Februar 2018 um 3:10 Uhr

  • Ich weiß nicht einmal, was ich damals gedacht habe … Danke @JonathanLidbeck, korrigiert!

    – Gsamaras

    4. März 2018 um 15:02 Uhr

  • Was ist, wenn 3 eine Variable ist? Wie machen wir das?

    – Yashoraj Agarwal

    20. September um 15:51 Uhr

  • @YashorajAgarwal gefällt das stackoverflow.com/q/25410690/2411320

    – Gsamaras

    Vor 2 Tagen

Benutzer-Avatar von anonymous
anonym

http://www.cplusplus.com/reference/clibrary/cstdio/scanf/

Verwenden Sie den Modifikator “Breite”.

%[*][width][modifiers]type

1410470cookie-checkLesen Sie nicht mehr als die Größe des Strings mit scanf()

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

Privacy policy