Für ein Projekt versuche ich, ein Int und einen String aus einem String zu lesen. Das einzige Problem ist sscanf() scheint beim Lesen an zu brechen %s wenn es ein Leerzeichen sieht. Gibt es eine Möglichkeit, diese Einschränkung zu umgehen? Hier ist ein Beispiel dafür, was ich versuche:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int age;
char* buffer;
buffer = malloc(200 * sizeof(char));
sscanf("19 cool kid", "%d %s", &age, buffer);
printf("%s is %d years old\n", buffer, age);
return 0;
}
Was es druckt ist: cool is 19 years old wo ich brauche cool kid is 19 years old. Weiß jemand, wie man das beheben kann?
Überprüfung des Ergebnisses von sscanf() ist ein guter erster Schritt zur Versicherung ageusw. erfolgreich gescannt.
– chux – Wiedereinsetzung von Monica
9. November 2015 um 15:00 Uhr
BrunoLM
Die folgende Zeile beginnt mit dem Lesen einer Zahl (%d) gefolgt von etwas anderem als Tabulatoren oder Zeilenumbrüchen (%[^\t\n]).
Vielen Dank. Außerdem funktioniert %d aus irgendeinem Grund nicht mehr, also habe ich % verwendet[0-9]. Danke noch einmal.
– SDLFunTimes
18. Mai 2010 um 5:34 Uhr
Aber … aber das ist katastrophal falsch! %[0-9] Bezeichner (und ähnliche) können nur zum Lesen von Zeichenfolgen verwendet werden. Und Sie lesen ein int (age) damit. Das kann und wird nicht funktionieren.
– AnT steht zu Russland
24. September 2010 um 2:11 Uhr
Wenn Sie eine lesen möchten intdu brauchst %d (oder vielleicht %i oder irgendetwas int-kompatibel). Aber nicht %[].
– AnT steht zu Russland
24. September 2010 um 2:15 Uhr
Du meinst, du liest ein int variabel mit an %[0-9] formatieren und dann wie im OP-Code drucken und es “funktioniert”? Tut mir leid, ich kann das kaum glauben 🙂 Nein, es funktioniert nicht. Ich kann mir vorstellen, dass Sie eine Zeichenfolge mit 3 Zeichen (oder weniger) in eine 4-Byte-Zeichenfolge quetschen können intaber sobald Sie das drucken int Sie werden Müll bekommen. Zu sagen, dass dieser zufällige Hack “funktioniert”, ist natürlich eine Beleidigung für das Wort “Arbeit” 🙂
– AnT steht zu Russland
24. September 2010 um 2:46 Uhr
@RyanS: Nein, ich bin es nicht, es ist die natürliche Dissonanz zwischen Saiten und Zahlen, die dich traurig macht. Sie sind nicht gleich. Manchmal macht es mich auch traurig, aber irgendwie habe ich gelernt, damit umzugehen. Warum oh warum, grausame Welt?!!!
– AnT steht zu Russland
19. Juni 2012 um 21:44 Uhr
Du willst die %c Konvertierungsbezeichner, der nur eine Folge von Zeichen ohne besondere Behandlung von Leerzeichen liest.
Beachten Sie, dass Sie den Puffer zuerst mit Nullen füllen müssen, da die %c Bezeichner schreibt kein Null-Terminator. Sie müssen auch die Anzahl der zu lesenden Zeichen angeben (ansonsten ist es standardmäßig nur 1):
Nun, das wird nicht für meinen Cousin funktionieren, der verdächtigerweise “George Fortescue Aloicious Broomhilda Doreen Beelzebub … Johanssen MacGregor” heißt 🙂
– paxdiablo
18. Mai 2010 um 4:17 Uhr
In der Tat – Ihr Cousin sollte sich beim OP beschweren, weil er nur einen Puffer von 200 Bytes zugewiesen hat;)
– Café
18. Mai 2010 um 4:23 Uhr
Guter Punkt und da Sie das Pufferüberlaufproblem mit meinen und Brunos Antworten erfasst haben, +1. Mach bei uns mit 🙂
– paxdiablo
18. Mai 2010 um 5:13 Uhr
@paxdiablo Nun, ich habe das gefunden %199c nützlich für mich, weil in meinem Fall die Zeichenfolge tatsächlich eine feste Länge hat.
– Wesley
27. Mai 2015 um 9:26 Uhr
paxdiablo
Wenn Sie bis zum Ende der Zeichenfolge scannen möchten (wobei ein Zeilenumbruch entfernt wird), verwenden Sie einfach:
Das ist, weil %s stimmt nur mit Zeichen überein, die keine Leerzeichen sind, und stoppt beim ersten gefundenen Leerzeichen. Das %[^\n] Formatbezeichner stimmt mit jedem Zeichen überein, das nicht (wegen ^) in der angegebenen Auswahl (was ein Zeilenumbruch ist). Mit anderen Worten, es passt zu jedem anderen Zeichen.
Denken Sie daran, dass Sie genügend Platz in Ihrem Puffer haben sollten, um die Zeichenfolge aufzunehmen, da Sie nicht sicher sein können, wie viel gelesen wird (ein guter Grund, sich von scanf/fscanf es sei denn, Sie verwenden bestimmte Feldbreiten).
(braucht man nicht * sizeof(char) denn das ist stets 1 per definitionem).
Also verursacht Ihr Cousin hier drüben einen Unfall, anstatt die Empörung zu erleiden, dass sein Name abgeschnitten wird? Auch mein Cousin, dessen Name noch verdächtiger ist (wobei das dritte Zeichen seines zweiten Namens ein Zeilenumbruch ist), ist unglücklich.
– Café
18. Mai 2010 um 4:23 Uhr
Der Kommentar muss im Zusammenhang mit den Kommentaren zu meiner Antwort gelesen werden.
– Café
18. Mai 2010 um 4:39 Uhr
ɲeuroburɳ
Da Sie die abschließende Zeichenfolge aus der Eingabe benötigen, können Sie verwenden %n (Anzahl der bisher verbrauchten Zeichen), um die Position zu erhalten, an der die abschließende Zeichenfolge beginnt. Dies vermeidet Speicherkopien und Probleme mit der Puffergröße, hat jedoch den Preis, dass Sie diese möglicherweise explizit ausführen müssen, wenn Sie eine Kopie wünschen.
const char *input = "19 cool kid";
int age;
int nameStart = 0;
sscanf(input, "%d %n", &age, &nameStart);
printf("%s is %d years old\n", input + nameStart, age);
Ausgänge:
cool kid is 19 years old
Ich denke, das ist, was Sie wollen, es macht genau das, was Sie angegeben haben.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int age;
char* buffer;
buffer = malloc(200 * sizeof(char));
sscanf("19 cool kid", "%d cool %s", &age, buffer);
printf("cool %s is %d years old\n", buffer, age);
return 0;
}
Das Format erwartet: zuerst eine Zahl (und setzt sie an die Stelle, auf die &age zeigt), dann Leerzeichen (null oder mehr), dann die literale Zeichenfolge „cool“, dann wieder Leerzeichen (null oder mehr) und schließlich eine Zeichenfolge (and setzen Sie das an welchen Pufferpunkten auch immer). Sie haben den “coolen” Teil in Ihrem Format-String vergessen, also nimmt das Format einfach an, dass dies der String ist, den Sie Buffer zuweisen wollten. Aber Sie möchten diese Zeichenfolge nicht zuweisen, sondern nur überspringen.
Alternativ könnten Sie auch einen Format-String wie: “%d %s %s” haben, aber dann müssen Sie ihm einen anderen Puffer zuweisen (mit einem anderen Namen) und ihn ausgeben als: “%s %s ist %d Jahre alt\n”.
Gefährlich: Der Puffer ist nicht zugewiesen, um auf irgendetwas zu zeigen. Sie möchten “char* buffer = malloc(100)” sagen, um Speicher dafür zu bekommen, wenn 100 Bytes ausreichen. Sie müssten dann eine Größe für %s angeben, die dazu passt (in diesem Fall 99, was Platz für ein 0-Terminator lässt, das sscanf() anhängt).
– Schweizer Franken
27. Mai 2018 um 16:57 Uhr
Gefährlich: Der Puffer ist nicht zugewiesen, um auf irgendetwas zu zeigen. Sie möchten “char* buffer = malloc(100)” sagen, um Speicher dafür zu bekommen, wenn 100 Bytes ausreichen. Sie müssten dann eine Größe für %s angeben, die dazu passt (in diesem Fall 99, was Platz für ein 0-Terminator lässt, das sscanf() anhängt).
– Schweizer Franken
27. Mai 2018 um 16:57 Uhr
14022300cookie-checkLesen eines Strings mit Leerzeichen mit sscanfyes
Überprüfung des Ergebnisses von
sscanf()
ist ein guter erster Schritt zur Versicherungage
usw. erfolgreich gescannt.– chux – Wiedereinsetzung von Monica
9. November 2015 um 15:00 Uhr