Was ist der Unterschied zwischen printf() und puts() in C?

Lesezeit: 5 Minuten

Benutzeravatar von alex
Alex

Ich weiß, dass Sie damit drucken können printf() und puts(). Das sehe ich auch printf() ermöglicht es Ihnen, Variablen zu interpolieren und zu formatieren.

Ist puts() nur eine primitive Version von printf(). Sollte es für alle möglichen verwendet werden printf() ohne Stringinterpolation?

  • puts() vs printf() – C/C++ Antworten

    – Anthony Forloney

    16. März 2010 um 13:05 Uhr

  • Nur eine Anmerkung zur Verwendung von printf anstelle von puts: Mach niemals a printf(variable) um eine Zeichenfolge zu drucken. Verwenden puts(variable) oder printf("%s', variable). Es gibt ein Sicherheitsrisiko bei der Verwendung einer variablen Formatzeichenfolge: Wenn die Variable von einem Angreifer geschrieben werden kann, kann er das Programm mithilfe von Formatzeichenfolgen angreifen.

    – Zan Luchs

    1. Dezember 2012 um 9:05 Uhr

puts ist einfacher als printf Beachten Sie jedoch, dass Ersteres automatisch einen Zeilenumbruch anhängt. Wenn Sie das nicht möchten, können Sie es tun fputs Ihre Zeichenfolge auf stdout oder verwenden printf.

  • Ich denke, es ist auch wichtig, die zusätzlichen Argumente zu erwähnen, die printf verwendet, um zusätzliche Variablen in die ausgegebene Zeichenfolge einzufügen.

    – Erutan409

    26. November 2015 um 22:59 Uhr

Benutzeravatar von leonbloy
leonbloy

(Darauf wird in einem Kommentar von Zan Lynx hingewiesen, aber ich denke, es verdient eine Antwort – da die akzeptierte Antwort es nicht erwähnt).

Der wesentliche Unterschied zw puts(mystr); und printf(mystr); ist, dass in letzterem das Argument als a interpretiert wird Formatierungszeichenfolge. Das Ergebnis ist oft dasselbe (mit Ausnahme des hinzugefügten Zeilenumbruchs), wenn der String keine Steuerzeichen enthält (%), aber wenn Sie sich darauf nicht verlassen können (falls mystr eine Variable statt eines Literals ist), sollten Sie nicht benutze es.

Es ist also im Allgemeinen gefährlich – und konzeptionell falsch – um eine dynamische Zeichenfolge als einzelnes Argument von zu übergeben printf:

char * myMessage;
// ... myMessage gets assigned at runtime, unpredictable content
printf(myMessage);  // <--- WRONG! (what if myMessage contains a '%' char?)
puts(myMessage);    // ok 
printf("%s\n",myMessage); // ok, equivalent to the previous, perhaps less efficient

Gleiches gilt für fputs vs fprintf (aber fputs fügt den Zeilenumbruch nicht hinzu).

  • In welcher Weise würde mit printf() weniger effizient sein? Zur Laufzeit? Zur Kompilierzeit?

    – franklin

    5. Januar 2015 um 16:51 Uhr

  • @franklin zur Laufzeit, weil printf muss die Formatzeichenfolge analysieren. Dies sollte jedoch normalerweise irrelevant sein. Außerdem könnte ein cleverer Compiler dies optimieren und die ersetzen printf mit Anruf an puts

    – Leonbloy

    6. Januar 2015 um 14:12 Uhr

Neben der Formatierung puts gibt bei Erfolg eine nicht negative Ganzzahl zurück oder EOF wenn erfolglos; während printf gibt die Anzahl der gedruckten Zeichen zurück (ohne die abschließende Null).

  • Als ich dies getestet habe, gibt puts die Anzahl der Zeichen in der Zeichenfolge einschließlich des abschließenden Zeichens zurück, während printf die Anzahl der ohne das abschließende Zeichen gedruckten Zeichen zurückgibt. Was technisch mit Ihrer Definition übereinstimmt, da erstere eine nicht negative ganze Zahl ist, aber ich bin mir nicht sicher, ob Sie das sagen wollten.

    – Lou

    22. April 2021 um 16:13 Uhr

  • @lou, bist du sicher, dass das zusätzliche Einschließen vom Nullterminator stammt, aber nicht das ‘\ n’?

    – Abweichler

    15. Januar um 0:25


Benutzeravatar von Hannu Balk
Hannu Balken

In einfachen Fällen konvertiert der Compiler Aufrufe in printf() Anrufe zu puts().

Beispielsweise wird der folgende Code zu dem Assembler-Code kompiliert, den ich als nächstes zeige.

#include <stdio.h>
main() {
    printf("Hello world!");
    return 0;
}
push rbp
mov rbp,rsp
mov edi,str.Helloworld!
call dword imp.puts
mov eax,0x0
pop rbp
ret

In diesem Beispiel habe ich GCC Version 4.7.2 verwendet und den Quellcode damit kompiliert gcc -o hello hello.c.

Benutzeravatar von Thomas Matthews
Thomas Matthäus

Durch meine Erfahrung, printf() schleppt mehr Code ein als puts() unabhängig von der Formatzeichenfolge.

Wenn ich die Formatierung nicht brauche, verwende ich sie nicht printf. Jedoch, fwrite zu stdout arbeitet viel schneller als puts.

static const char my_text[] = "Using fwrite.\n";
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout);

Hinweis: pro Kommentar ist ‘\0’ eine ganzzahlige Konstante. Der richtige Ausdruck sollte sein sizeof(char) wie aus den Kommentaren hervorgeht.

  • “fwrite to stdout funktioniert viel schneller als puts.” – Was könnte der Grund sein?

    – Antony Hatchkins

    15. März 2013 um 13:08 Uhr

  • @AntonyHatchkins Es ist normalerweise nicht “viel” schneller. puts() muss jedoch jedes Mal einen strlen()-Aufruf für Ihren String ausführen, während dies vermieden werden kann, wenn die Größe mit fwrite() bekannt ist. Das ist so ziemlich der einzige wirkliche Beitrag zu einem Leistungsunterschied.

    – Wiz

    18. November 2013 um 8:54 Uhr

  • Diese Antwort ist falsch. '\0' Typ hat intalso wird dies auf den meisten Systemen gedruckt Using fwrit. Wenn Sie 1 Byte weniger drucken möchten, verwenden Sie einfach 1. sizeof (char)was wahrscheinlich das ist, was Sie hier beabsichtigt haben, ist garantiert 1.

    – Bradley Garagan

    17. August 2015 um 18:32 Uhr

Benutzeravatar von Koray Tugay
Koray Tugay

int puts(const char *s);

setzt () schreibt den String s und ein abschließendes Newline nach stdout.

int printf(const char *format, ...);

Die Funktion printf() schreibt die Ausgabe nach stdout, gesteuert durch einen Formatstring, der angibt, wie nachfolgende Argumente für die Ausgabe konvertiert werden.

Ich werde diese Gelegenheit nutzen, um Sie zu bitten, die Dokumentation zu lesen.

  • “fwrite to stdout funktioniert viel schneller als puts.” – Was könnte der Grund sein?

    – Antony Hatchkins

    15. März 2013 um 13:08 Uhr

  • @AntonyHatchkins Es ist normalerweise nicht “viel” schneller. puts() muss jedoch jedes Mal einen strlen()-Aufruf für Ihren String ausführen, während dies vermieden werden kann, wenn die Größe mit fwrite() bekannt ist. Das ist so ziemlich der einzige wirkliche Beitrag zu einem Leistungsunterschied.

    – Wiz

    18. November 2013 um 8:54 Uhr

  • Diese Antwort ist falsch. '\0' Typ hat intalso wird dies auf den meisten Systemen gedruckt Using fwrit. Wenn Sie 1 Byte weniger drucken möchten, verwenden Sie einfach 1. sizeof (char)was wahrscheinlich das ist, was Sie hier beabsichtigt haben, ist garantiert 1.

    – Bradley Garagan

    17. August 2015 um 18:32 Uhr

Recht, printf könnte als eine leistungsfähigere Version von angesehen werden puts. printf bietet die Möglichkeit dazu Format Variablen für die Ausgabe mit Formatbezeichnern wie z %s, %d, %lfetc…

1425790cookie-checkWas ist der Unterschied zwischen printf() und puts() in C?

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

Privacy policy