2016-08-30 2 views
3

Nur aus Neugier:Kann printf() zurück von strlen() abweichen?

#include <stdio.h> 
#include <string.h> 

enum { BIG_NUMBER = 1024 }; 

int main(void) 
{ 
    char mysterious_string[BIG_NUMBER]; 

    if (scanf("%1023s", mysterious_string) == 1) { 

     if (printf("%s", mysterious_string) != strlen(mysterious_string)) { 
      // Can this state occur? 
     } 
    } 
    return 0; 
} 

Kann die innere 'wenn' true zurück? Kann ich diesen beiden Funktionen blind vertrauen (printf() und strlen()), um den richtigen Wert zurückzugeben?

+1

Vermutlich kann man davon ausgehen, dass die Zeichenfolge gültig ist? (Nicht allgemein zutreffend für den obigen Code, FWIW) –

+0

@OliverCharlesworth ja, mein Fehler, bearbeitet die Frage \ 0 –

+0

Wenn die Zeichenfolge ein '\ n' Zeichen enthält, wird es auf einigen Plattformen geändert, um ein' \ r' einzuschließen in der Ausgabe und wenn ja, wird dieses zusätzliche Zeichen in der Rückkehr von 'printf()' berücksichtigt? Wenn ja, dann nein, sie können nicht garantiert werden, dass sie gleich sind. – mah

Antwort

6

Es kann durchaus anders sein.

Wenn printf fehlschlägt (aus verschiedenen Gründen), wird eine negative Zahl zurückgegeben, die nicht mit dem von strlen zurückgegebenen Wert übereinstimmt. In allen anderen Fällen wird es dasselbe sein.

Hinweis: Angenommen, die Zeichenfolge ist null terminiert und scanf funktioniert wie erwartet.

+0

Wenn es nicht null terminiert ist, ist es keine Zeichenfolge. –

+0

@keitththompson Redundanz ist nicht unbedingt schlecht ... –

4

Kann das 'if'-Ergebnis wahr sein? Kann ich blind diesen beiden Funktionen vertrauen, um den richtigen Wert zurückzugeben?

Ja, es kann wahr (nicht gleich) zurückgeben.
Beide Funktionen können vertrauenswürdig sein, um den "richtigen" Wert mit einem kompatiblen Compiler und konformem Code zurückzugeben. Der "richtige" Wert aus diesen 2 Funktionen kann jedoch abweichen.


Mindestens 3 Fälle:

  1. printf() schlägt fehl und gibt -1 zurück @Ben, möglich durch I/O-Fehler oder aus anderen Gründen. Dieser -1 wird in SIZE_MAX als Teil des vergleichen.

  2. strlen(mysterious_string) > INT_MAX. printf() gibt eine int zurück, aber eine Zeichenfolge kann viel länger sein. strlen() gibt size_t zurück, ein vorzeichenloser Typ, der den positiven Bereich von int überschreiten kann.

  3. Die "%s" Konvertierung überschreitet die Grenzwerte für die Umgebung, dann können die Ergebnisse abweichen. scanf("%s", mysterious_string); unterliegt nicht dieser Grenze.

Die Anzahl von Zeichen, die zumindest von einer einzelnen Umwandlung hergestellt werden können, 4095. C11dr §7.21.6.1 15


FWIW, Druck auf einem Windows-Rechner Druck sein soll mit der üblichen \n ->\r\n Textmodus Übersetzung noch eine 1 aus fprintf(text_file, "%s", "\n") zurückgegeben, obwohl 2 Zeichen in die Datei geschrieben wurden.