2009-07-22 15 views
2

Ich habe einen Kompilierungsfehler auf den folgenden Code:C Char-Array ist kein String-Muster?

printf ((char *) Puffer);

und die Fehlermeldung, die ich erhalte ist:

cc1: Format kein Stringliteral und keine Format Argumente ...

Ich vermute, es gibt einige Bibliotheken, die ich zu installieren vergessen zu, wie ich in der Lage war, den Code ohne Fehler auf dem anderen Rechner zu kompilieren und auszuführen ...

PS: Die Frage steigt mit der Tatsache, dass ich den gleichen Code auf einer anderen Maschine ausführen konnte ... Ich vermute Ein Unterschied in der gcc-Version könnte ein Problem wie dieses verursachen?

+0

Der Text klingt sehr ähnlich wie es sollte eine Warnung und kein Fehler sein. Können Sie mehr Informationen über den von Ihnen verwendeten Compiler und welche Optionen geben? –

+0

post die Definition von 'Puffer' –

+0

Mein Speicher ist ein wenig verschwommen auf diese, aber es ist oft möglich, Warnungen auf Fehler zu fördern. –

Antwort

5

Neuere GCC-Versionen versuchen, die an printf und ähnliche Funktionen übergebene Formatzeichenfolge zu analysieren und festzustellen, ob die Argumentliste korrekt mit der Formatzeichenfolge übereinstimmt. Es kann dies nicht tun, weil Sie ihm einen Puffer für das erste Argument übergeben haben, was normalerweise eine Formatzeichenfolge wäre.

Ihr Code ist nicht falsch C, es ist nur eine schlechte Verwendung von C. Wie bereits erwähnt, sollten Sie "% s" als Formatstring verwenden, um eine einzelne Zeichenfolge zu drucken. Dies schützt Sie vor einer Klasse von Fehlern, die Prozentzeichen in Ihrer Zeichenfolge enthalten, wenn Sie die Eingabe nicht steuern. Es ist eine bewährte Methode, niemals ein String-Literal als erstes Argument an die printf- oder sprintf-Funktionsfamilie zu übergeben.

+0

sehr gut, klare Antwort –

+0

Ich denke, du hast das Problem genagelt :) – Lawrence

4

versuchen

printf ("% s", (char *) Puffer); Diese

;-)

+0

Die Frage steigt mit der Tatsache, dass ich den gleichen Code auf einer anderen Maschine ausführen konnte ... Ich vermute, ein Unterschied in der gcc-Version könnte ein Problem wie dieses verursachen? – Lawrence

+0

Nun, es klingt so, als ob die andere Maschine nicht Standard ist C – tkotitan

+0

printf (% s) ist eine schlechte Übung, da Sie sehr wahrscheinlich den Stapel zerstören, wenn Ihre Zeichenfolge Sonderzeichen enthält (% d,% s, usw.). Das erste Argument von printf sollte immer ein String-Literal sein. Ich nehme an, dass verschiedene Versionen von GCC strenger sind, ob sie es dir erlauben oder nicht. – Falaina

0

ist eine Warnung für Ihre Sicherheit, kein Fehler. Dieser neue Compiler ist anscheinend strenger. Ich glaube nicht, dass es tatsächlich illegal ist in C, so dass der Compiler eine Option haben sollte, um dies als einen Fehler zu deaktivieren.

Allerdings möchten Sie eigentlich nie etwas anderes als ein String-Literal als erstes Argument für printf übergeben. Der Grund dafür, dass dies eine so schreckliche Idee ist, dass der Compiler eine spezielle eingebaute Kontrolle hat, um Sie davor zu warnen: Angenommen, die nicht-literale Zeichenfolge, die Sie als erstes Argument an printf übergeben, enthält printf Formatierungszeichen. printf wird dann versuchen, auf zweite, dritte, vierte usw. Argumente zuzugreifen, die Sie nicht wirklich übergeben haben, und möglicherweise Ihr Programm zum Absturz bringen, indem Sie versuchen, dies zu tun. Wenn das nicht-literale erste Argument tatsächlich vom Benutzer bereitgestellt wird, ist das Problem noch schlimmer, da ein böswilliger Benutzer Ihr Programm nach Belieben abstürzen kann.

+0

Normalerweise können Sie das tun, was Sie mit einem String-Literal für eine Formatzeichenfolge tun möchten, insbesondere da der Rest der Anweisung zur Kompilierzeit festgelegt ist. Es mag Fälle geben, in denen es vorzuziehen ist, eine nicht-literale Zeichenfolge zu übergeben, aber Tyler weist darauf hin, dass dies eine gefährliche Vorgehensweise ist, und Sie sollten auf keinen Fall Benutzereingaben auf diese Weise verwenden. –

1

Diese Warnung wird von gcc erzeugt, wenn

-Wformat-nonliteral 

gesetzt. Es ist nicht Teil von -Wall oder -Wextra (zumindest für Version 4.4.0), also lass es einfach fallen, wenn du willst, dass der Code warnungsfrei kompiliert wird.