2015-01-06 12 views
6

lerne ich einige C und am scanf von this tutorial lesen, wo der folgende Codeblock enthalten ist:Warum erhalte ich Warnungen zu diesem Codebeispiel? Was ist richtig?

#include <stdio.h> 

int main() 
{ 
    char str1[20], str2[30]; 

    printf("Enter name: "); 
    scanf("%s", &str1); 

    printf("Enter your website name: "); 
    scanf("%s", &str2); 

    printf("Entered Name: %s\n", str1); 
    printf("Entered Website:%s", str2); 

    return(0); 
} 

ich jedoch Warnungen:

"Format specifies type 'char *' but the argument has type 'char (*)[20]' 

Ist das Tutorial nicht in Ordnung?

+10

Hören Sie sofort auf, C aus diesem Tutorial zu lernen. Es ist falsch. –

+1

@Doug Smith Berücksichtigen Sie, dass sogar veröffentlichte Bücher von bekannten Autoren Programmfehler enthalten :) –

+1

@Doug Smith Übrigens in diesem Satz "Ich bin ein Webdesigner, der mit iOS aus England herumspielt" aus England iOS oder du? :) –

Antwort

13

Dies sollte für Sie arbeiten:

#include <stdio.h> 

int main() 
{ 
    char str1[20], str2[30]; 

    printf("Enter name: "); 
    scanf("%19s", str1); 
     //^^ ^Removed address operator 
     //So only the right amount of characters gets read 

    printf("Enter your website name: "); 
    scanf(" %29s", str2); 
     //^ Added space to catch line breaks from the buffer 

    printf("Entered Name: %s\n", str1); 
    printf("Entered Website:%s", str2); 

    return(0); 
} 
+0

Tutorial war dann eindeutig falsch? –

+0

@DougSmith Ja, sehe auch meine Kommentare, was ich geändert habe, hoffe meine Antwort hilft Ihnen! (Auch wenn dies ein Tutorial wäre, würde ich ein neues suchen) – Rizier123

+0

Das ist besser als der ursprüngliche Code, aber es ist immer noch anfällig für einen Pufferüberlauf. –

7

Es gibt einen Fehler im Beispiel des Lernprogramms.

Wechsel:

scanf("%s", &str1); 

zu

scanf("%s", str1); 

s Konvertierungsspezifizierer erfordert einen Zeiger auf char aber Sie einen Zeiger auf ein Array übergeben.

+1

Ah, also war das Tutorial falsch? –

+5

In der Tat ist das Tutorial fehlerhaft. – ouah

3

Die Linien

scanf("%s", &str1); 

und

scanf("%s", &str2); 

sind in der Tat falsch (zumindest, sie enthalten beide einen Tippfehler). Sie sollten geschrieben werden als

scanf("%s", str1); // no & operator 

und

scanf("%s", str2); // ditto 

Arrays und Array-Ausdrücke sind spezielle in C. Außer, wenn es die Operanden der sizeof oder einstellige & Operatoren oder ein Stringliteral Wird verwendet, um ein anderes Array in einer Deklaration zu initialisieren, wird ein Ausdruck vom Typ "N-Element-Array von T" in einen Ausdruck vom Typ "Zeiger auf T" und den Wert von expressi konvertiert (zerfallen) on ist die Adresse des ersten Elements des Arrays.

Die Ausdruckstr1 hat Typ "20-Element-Array von char". Wenn str1 in einem Kontext auftritt, in dem es nicht der Operand der Operatoren sizeof oder unary & ist, wird es in einen Ausdruck vom Typ "Zeiger auf char" konvertiert, und der Wert des Ausdrucks ist derselbe wie &str1[0]; Aus diesem Grund müssen Sie & nicht zum Lesen von Strings verwenden, da der Array-Ausdruck als Zeiger behandelt wird. Wenn es jedoch der Operand des unären &-Operators ist, gilt die Konvertierungsregel nicht, und der Typ des Ausdrucks &str1 ist "Zeiger auf ein 20-Elemente-Array von char" (char (*)[20]). Daher deine Warnung.

Der Wert vonstr1 und &str1 werden das gleiche sein (die Adresse der ersten Elementanordnung ist das gleiche wie die Adresse des Arrays), aber die Arten der Ausdrücke sind unterschiedlich, und Fragen eingeben. Ein Zeiger auf char wird anders als ein Zeiger auf ein Array von char behandelt.

90% der C Bücher und Tutorials sind crap; sehr skeptisch gegenüber jeder C-Referenz sein, die nicht der eigentliche Standard ist. Harbison & Steele's C: A Reference Manual (zZ 5. Ausgabe) ist seit den späten 80er Jahren meine Referenz, aber selbst es hat kleine Fehler.

Verwandte Themen