Warum enthält der printf-Formatstring von C sowohl %c als auch %s?

Lesezeit: 10 Minuten

Warum hat der printf-Formatstring von C beides? %c und %s?

ich weiß das %c repräsentiert ein einzelnes Zeichen und %s stellt eine nullterminierte Zeichenfolge dar, aber wäre die Zeichenfolgendarstellung allein nicht ausreichend?

  • Wahrscheinlich um zwischen einer nullterminierten Zeichenfolge und einem Zeichen zu unterscheiden. Wenn sie es nur getan hätten %sdann muss auch jedes einzelne Zeichen nullterminiert werden. Zeichen c = ‘a’;in diesem Fall c muss nullterminiert sein. Das ist aber meine Vermutung 🙂

    – Mahesh

    1. Juni 2012 um 7:18 Uhr


  • @ Mahesh: Warum nicht als Antwort, besonders wenn Es ist die Antwort

    – Alok Speichern

    1. Juni 2012 um 7:20 Uhr

  • Häh? Was ist, wenn Sie nur ein einzelnes Zeichen einfügen möchten, warum sollten Sie dann eine NUL anhängen müssen? Oder habe ich bei dieser Frage etwas nicht verstanden?

    – Christian Rau

    1. Juni 2012 um 7:21 Uhr

  • @Mahesh Ihre Annahme ist meiner Meinung nach die Antwort auf diese Frage

    – Krishnabhadra

    1. Juni 2012 um 7:21 Uhr

  • %c erwartet ein Datum von char type – ein Wertprimitiv. %s erwartet ein Datum von char * Typ, ein Zeiger. Der Unterschied zwischen diesen ist in C enorm, obwohl sie beide für Text gelten.

    – Russell Borogove

    1. Juni 2012 um 19:02 Uhr

Wahrscheinlich um zwischen einer nullterminierten Zeichenfolge und einem Zeichen zu unterscheiden. Wenn sie es nur getan hätten %sdann muss auch jedes einzelne Zeichen nullterminiert werden.

char c="a";

Im oben genannten Fall c muss nullterminiert sein. Das ist aber meine Vermutung 🙂

  • Keine wirkliche Antwort, denn das könnte vermieden werden %.1s

    – Jens Gustedt

    1. Juni 2012 um 7:35 Uhr

  • @Merlin Das habe ich nicht gesagt. Wahrscheinlich könnte meine Satzbildung verwirrend sein. Wie Sie vielleicht wissen, die Formatzeichenfolge für den Formatbezeichner %s muss sein nullterminiert. Wenn es keine gibt %c in der Sprache, dann in meinem obigen Beispiel, Bezeichner c muss nullterminiert sein, um mit dem Formatbezeichner verwendet werden zu können %s.

    – Mahesh

    1. Juni 2012 um 14:24 Uhr


  • @mahesh Eine verwirrende Antwort ist schlimmer als eine falsche Antwort zu geben … Ich kann nicht glauben, dass Sie darüber streiten.

    – Moog

    1. Juni 2012 um 14:50 Uhr

  • -1 Dies ist eine schlechte Antwort … Der Grund dafür printf("%s", c) nicht funktionieren würde, liegt nicht an der Null-Terminierung, sondern daran printf erwartet %s auf einen Speicherort zeigen, während c ist ein Zeichenwert. Nullterminierung ist der Grund printf("%s", &c) würde nicht funktionieren, aber selbst wenn es funktionieren würde, mit einem %c Kennung würde still sinnvoll, weil erfordernd &c widerspricht der Art und Weise, wie alle anderen Variablentypen gedruckt werden. Also nur gesagt “es liegt an der nullterminierung” ist falsch.

    – BlueRaja – Danny Pflughoeft

    1. Juni 2012 um 17:37 Uhr


  • Ich verstehe nicht, wie 74 Personen dachten, dass dies die richtigen Antworten waren, da nicht erwähnt wird, dass Sie eine bestehen müssten char* sogar das eine Zeichen zum Drucken zu bekommen %s. Ich wiederhole nur, was BlueRaja gesagt hat

    – Ruan Mendes

    2. Juni 2012 um 9:00 Uhr


Benutzeravatar von Luchian Grigore
Luchian Grigore

%s gibt Zeichen aus, bis es a erreicht 0 (oder '\0'gleiche Sache).

Wenn Sie nur eine haben char x;drucken Sie es mit printf("%s", &x);Sie müssten die Adresse angeben, da %s erwartet ein char* – würde zu unerwarteten Ergebnissen führen, wie &x + 1 möglicherweise nicht 0.

Sie konnten also nicht einfach ein einzelnes Zeichen drucken, es sei denn, es war nullterminiert (sehr ineffizient).

BEARBEITEN: Wie andere bereits angemerkt haben, erwarten die beiden unterschiedliche Dinge in den var args-Parametern – einer ein Zeiger, der andere ein einzelnes Zeichen. Aber dieser Unterschied ist etwas deutlich.

  • das solltest du erwähnen %s dauert einen Zeiger, während %c nimmt selbst einen Charakter an.

    – Matt

    1. Juni 2012 um 7:21 Uhr

  • Und was noch wichtiger ist, Sie können ein Zeichen nur drucken, wenn seine Adresse genommen werden kann. Das würde zB das Drucken der Rückgaben von Funktionen ausschließen und auch Variablen registrieren.

    – Jens Gustedt

    1. Juni 2012 um 7:27 Uhr

  • Sie könnten das Problem der Nullterminierung vermeiden, indem Sie eine Genauigkeit angeben.

    – Jens Gustedt

    1. Juni 2012 um 7:30 Uhr

Benutzeravatar von Jens Gustedt
Jens Gustedt

Das von anderen erwähnte Problem, dass ein einzelnes Zeichen nullterminiert werden müsste, ist nicht real. Dies könnte durch eine Präzisierung des Formats behandelt werden %.1s würde den Trick machen.

Wichtiger ist aus meiner Sicht, dass für %s In jeder Form müssten Sie einen Zeiger auf ein oder mehrere Zeichen angeben. Das würde bedeuten, dass Sie keine Rvalues ​​(berechnete Ausdrücke, Funktionsrückgaben usw.) drucken oder Variablen registrieren könnten.

Bearbeiten: Ich bin wirklich sauer auf die Reaktion auf diese Antwort, also werde ich das wahrscheinlich löschen, das ist es wirklich nicht wert. Es scheint, dass die Leute darauf reagieren, ohne die Frage überhaupt gelesen zu haben oder zu wissen, wie man die Technik der Frage einschätzt.

Um das klarzustellen: Ich sage nicht, dass Sie es vorziehen sollten %.1s Über %c. Ich sage nur, warum %c können nicht dadurch ersetzt werden, dass sie anders sind, als die andere Antwort vorgibt zu sagen. Diese anderen Antworten sind einfach technisch falsch. Nullterminierung ist kein Problem mit %s.

  • @LuchianGrigore: Nein, ich sage nicht, dass das jemand bevorzugen sollte, im Gegenteil. Ich sage, dass %.1s hätte die Funktionalität, nur ein Zeichen zu drucken, das nicht einmal nullterminiert sein darf, daher ist die Nullterminierung kein gültiger Einwand gegen “einführen”. %c.

    – Jens Gustedt

    1. Juni 2012 um 7:38 Uhr


  • @Als würde %.1s erwarte a char oder ein char*?

    – Luchian Grigore

    1. Juni 2012 um 7:48 Uhr

  • @LuchianGrigore, das sagt niemand. Meine Antwort besagt einfach, dass die Nullterminierung nicht das richtige Argument ist, aber dass die Adresse des Objekts ein Argument ist.

    – Jens Gustedt

    1. Juni 2012 um 8:12 Uhr

  • @JoshuaDrake, hast du meine Antwort gelesen. Ich finde das Downvoting dafür wirklich übertrieben. Ich sage nicht, dass jeder verwenden sollte %.1s zum Drucken eines Zeichens. Das war nicht die Frage. Die Frage war ob %c war unbedingt erforderlich. Und ich gebe eine bejahende Antwort darauf, indem ich nur behaupte, dass die Gründe anders sind als die in den anderen Antworten angegebenen.

    – Jens Gustedt

    1. Juni 2012 um 17:40 Uhr

  • @JoshuaDrake: -1, weil du die Antwort nicht gelesen hast. Die Frage fragt, warum X in C existiert, und diese Antwort erklärt deutlich, dass X existieren MUSS, um mit rvalues ​​arbeiten zu können. Ohne Berücksichtigung von rvalues ​​hätten die Sprach-/Bibliotheksdesigner es wahrscheinlich bei %.1s belassen (und genauso wahrscheinlich SOLLTEN), da es den printf sauberer (und damit lesbarer) macht. Ohne c könnte das Drucken des Ergebnisses einer Funktion, die ein einzelnes Zeichen zurückgibt, ziemlich komplex werden (insbesondere wenn mehrere Funktionen mit Nebeneffekten aufgerufen werden und die reihenfolgeabhängig sind).

    – jmoreno

    1. Juni 2012 um 18:17 Uhr

Benutzeravatar von AndersK
AndersK

Die printf-Funktion ist eine variadische Funktion, was bedeutet, dass sie eine variable Anzahl von Argumenten hat. Argumente werden auf den Stapel geschoben, bevor die Funktion (printf) aufgerufen wird. Damit die Funktion printf den Stack verwenden kann, muss sie Informationen darüber kennen, was sich im Stack befindet. Zu diesem Zweck wird der Formatstring verwendet.

z.B

printf( "%c", ch );    tells the function the argument 'ch' 
                       is to be interpreted as a character and sizeof(char)

wohingegen

printf( "%s", s );   tells the function the argument 's' is a pointer 
                     to a null terminated string sizeof(char*)

es ist innerhalb der printf-Funktion nicht möglich, Stack-Inhalte anderweitig zu bestimmen, zB zwischen ‘ch’ und ‘s’ zu unterscheiden, weil es in C keine Typprüfung zur Laufzeit gibt.

Benutzeravatar von Ruan Mendes
Ruan Mendes

%s sagt, drucke alle Zeichen, bis du eine Null findest (behandle die Variable als Zeiger).

%c sagt, drucke nur ein Zeichen (behandle die Variable als Zeichencode)

Verwenden %s für ein Zeichen nicht funktioniert, weil das Zeichen wie ein Zeiger behandelt wird, dann wird es versuchen, alle Zeichen nach dieser Stelle im Speicher zu drucken, bis es eine Null findet

Von den anderen Antworten stehlen um es mal anders zu erklären.

Wenn Sie ein Zeichen mit drucken möchten %skönnten Sie Folgendes verwenden, um ihm eine Adresse eines Zeichens richtig zu übergeben und zu verhindern, dass Müll auf den Bildschirm geschrieben wird, bis eine Null gefunden wird.

char c="c";
printf('%.1s', &c);

  • Dies ist nicht ganz richtig. Die Verwendung von %s für ein Zeichen kann völlig unerwartete Dinge bewirken, da es ein Zeichen als Zeiger auf ein Zeichen interpretiert, das wahrscheinlich auf eine ungültige Position zeigt.

    – Matt

    1. Juni 2012 um 7:22 Uhr

  • Nur um es klarzustellen (da viele Leute diese Konzepte verwechseln), wird eine Zeichenfolge durch eine Null abgeschlossen Charakternicht zu verwechseln mit einer Null Zeiger.

    – Keith Thompson

    3. Juni 2012 um 5:21 Uhr

  • @KeithThompson Nur um die Leute zu verwirren: Nullzeichen '\0' und Nullzeiger werden beide intern dargestellt als 0 🙂

    – Ruan Mendes

    7. Juni 2012 um 0:20 Uhr

  • @JuanMendes: Nein, sie können beide vertreten sein im Quellcode wie 0. Ihre internen Repräsentationen können sehr unterschiedlich sein; ein Nullzeichen hat normalerweise 8 Bits, während ein Nullzeiger normalerweise 32 oder 64 Bits hat. Darüber hinaus ist die interne Darstellung eines Nullzeigers nicht notwendigerweise alle Bits-Null (obwohl es sehr häufig der Fall ist).

    – Keith Thompson

    7. Juni 2012 um 5:05 Uhr

  • @Keith Die fragliche Sprache ist C, und ich habe noch nie davon gehört, dass die interne Darstellung etwas anderes als eine 0 ist. Deshalb können Sie eine der folgenden verwenden. if (pointer) oder if (pointer != 0 ) oder if(pointer != NULL ) Außerdem denke ich, dass 0s mit 8, 16, 32 Bits nicht sehr unterschiedlich sind. bytes.com/topic/c/answers/213647-null-c

    – Ruan Mendes

    7. Juni 2012 um 18:04 Uhr


Benutzeravatar von Keith Thompson
Keith Thompson

Zum %smüssen wir die Adresse der Zeichenfolge angeben, nicht ihren Wert.

Zum %cgeben wir den Wert von Zeichen an.

Wenn wir die benutzten %s Anstatt von %cwie würden wir a '\0' nach den Charakteren?

  • Dies ist nicht ganz richtig. Die Verwendung von %s für ein Zeichen kann völlig unerwartete Dinge bewirken, da es ein Zeichen als Zeiger auf ein Zeichen interpretiert, das wahrscheinlich auf eine ungültige Position zeigt.

    – Matt

    1. Juni 2012 um 7:22 Uhr

  • Nur um es klarzustellen (da viele Leute diese Konzepte verwechseln), wird eine Zeichenfolge durch eine Null abgeschlossen Charakternicht zu verwechseln mit einer Null Zeiger.

    – Keith Thompson

    3. Juni 2012 um 5:21 Uhr

  • @KeithThompson Nur um die Leute zu verwirren: Nullzeichen '\0' und Nullzeiger werden beide intern dargestellt als 0 🙂

    – Ruan Mendes

    7. Juni 2012 um 0:20 Uhr

  • @JuanMendes: Nein, sie können beide vertreten sein im Quellcode wie 0. Ihre internen Repräsentationen können sehr unterschiedlich sein; ein Nullzeichen hat normalerweise 8 Bits, während ein Nullzeiger normalerweise 32 oder 64 Bits hat. Darüber hinaus ist die interne Darstellung eines Nullzeigers nicht notwendigerweise alle Bits-Null (obwohl es sehr häufig der Fall ist).

    – Keith Thompson

    7. Juni 2012 um 5:05 Uhr

  • @Keith Die fragliche Sprache ist C, und ich habe noch nie davon gehört, dass die interne Darstellung etwas anderes als eine 0 ist. Deshalb können Sie eine der folgenden verwenden. if (pointer) oder if (pointer != 0 ) oder if(pointer != NULL ) Außerdem denke ich, dass 0s mit 8, 16, 32 Bits nicht sehr unterschiedlich sind. bytes.com/topic/c/answers/213647-null-c

    – Ruan Mendes

    7. Juni 2012 um 18:04 Uhr


Benutzeravatar von trumpetlicks
Trompetenschläge

Ich möchte dieser lustigen Frage einen weiteren Gesichtspunkt hinzufügen.

Wirklich kommt es darauf an, Daten einzugeben. Ich habe hier Antworten gesehen, die besagen, dass Sie einen Zeiger auf das Zeichen und einen angeben könnten

"%.1s"

Das könnte tatsächlich stimmen. Aber die Antwort liegt darin, dass der C-Designer versucht, dem Programmierer Flexibilität zu bieten, und in der Tat eine (wenn auch kleine) Möglichkeit, den Platzbedarf Ihrer Anwendung zu verringern.

Manchmal möchte ein Programmierer eine Reihe von If-Else-Anweisungen oder einen Switch-Case ausführen, bei dem einfach ein Zeichen basierend auf dem Status ausgegeben werden muss. Aus diesem Grund könnte die Hartcodierung der Zeichen tatsächlich weniger Platz im Speicher beanspruchen, da die einzelnen Zeichen 8 Bit groß sind im Vergleich zum Zeiger, der 32 oder 64 Bit groß ist (für 64-Bit-Computer). Ein Zeiger nimmt mehr Platz im Speicher ein.

Wenn Sie die Größe verringern möchten, indem Sie tatsächliche Zeichen anstelle von Zeigern auf Zeichen verwenden, gibt es zwei Möglichkeiten, dies innerhalb von printf-Typen von Operatoren zu tun. Eine wäre, die .1s wegzutasten, aber wie soll die Routine sicher wissen, dass Sie wirklich einen Zeichentyp anstelle eines Zeigers auf ein Zeichen oder einen Zeiger auf eine Zeichenfolge (Array von Zeichen) bereitstellen? Aus diesem Grund haben sie sich für das “%c” entschieden, da es anders ist.

Lustige Frage 🙂

1416760cookie-checkWarum enthält der printf-Formatstring von C sowohl %c als auch %s?

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

Privacy policy