2015-01-06 11 views
6

tôi đang học một số C, và được đọc lên trên scanf từ this tutorial nơi khối mã sau được bao gồm:Tại sao tôi nhận được cảnh báo về ví dụ mã này? Điều gì là thích hợp?

#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); 
} 

Tuy nhiên tôi nhận được cảnh báo rằng:

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

là hướng dẫn sai?

+10

Dừng ngay lập tức học C từ hướng dẫn đó. Điều đó là sai. –

+1

@Doug Smith Hãy xem xét rằng ngay cả những cuốn sách được xuất bản của các tác giả nổi tiếng có lỗi trong các ví dụ chương trình. :) –

+1

@Doug Smith Bằng cách này trong cụm từ "Tôi là một nhà thiết kế web chơi xung quanh với iOS từ Anh" là gì từ Anh iOS hay bạn? :) –

Trả lời

13

này nên làm việc cho bạn:

#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

Hướng dẫn rõ ràng là sai? –

+0

@DougSmith Có, cũng xem nhận xét của tôi những gì tôi đã thay đổi, hy vọng câu trả lời của tôi sẽ giúp bạn! (Ngoài ra nếu đây là một hướng dẫn tôi sẽ tìm kiếm một cái mới) – Rizier123

+0

Đó là tốt hơn so với mã ban đầu, nhưng nó vẫn còn dễ bị tràn bộ đệm. –

7

Có lỗi trong ví dụ về hướng dẫn.

Thay đổi:

scanf("%s", &str1); 

để

scanf("%s", str1); 

s xác định chuyển đổi đòi hỏi một con trỏ đến char nhưng bạn đang đi qua một con trỏ đến một mảng.

+1

Ah, vậy hướng dẫn đã sai? –

+5

Thật vậy, hướng dẫn là lỗi. – ouah

3

Các dòng

scanf("%s", &str1); 

scanf("%s", &str2); 

có thực sự sai (ít nhất, cả hai đều có chứa một lỗi đánh máy). Họ nên được viết như

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

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

Mảng và các biểu thức mảng là đặc biệt trong C. Trừ khi nó là toán hạng của sizeof hoặc unary & nhà khai thác, hoặc là một chuỗi chữ được sử dụng để khởi tạo một mảng khác trong khai báo, biểu thức thuộc loại "phần tử N số T" sẽ được chuyển đổi (phân rã) thành biểu thức loại "con trỏ đến T" và giá trị của expressi trên sẽ là địa chỉ của phần tử đầu tiên của mảng.

Biểu thức str1 có loại "20 phần tử mảng char". Nếu str1 xuất hiện trong ngữ cảnh không phải là toán hạng của các toán tử sizeof hoặc unary &, nó sẽ được chuyển thành biểu thức loại "con trỏ đến char" và giá trị của biểu thức sẽ giống như &str1[0]; đây là lý do tại sao bạn không cần phải sử dụng các & cho các chuỗi đọc, vì biểu thức mảng sẽ được coi là một con trỏ. Tuy nhiên, khi đó là toán hạng của toán tử & đơn nhất, quy tắc chuyển đổi không áp dụng và loại biểu thức &str1 là "con trỏ tới mảng 20 phần tử của char" (char (*)[20]). Do đó cảnh báo của bạn.

Giá trị của str1&str1 sẽ giống nhau (địa chỉ của mảng phần tử đầu tiên là giống như địa chỉ của mảng), nhưng các loại của biểu thức là khác nhau, và gõ các vấn đề. Một con trỏ đến char sẽ được xử lý khác với con trỏ tới mảng char.

90% sách và hướng dẫn C là crap; rất hoài nghi về bất kỳ tham chiếu C nào không phải là tiêu chuẩn thực tế. Harbison & Steele's C: A Reference Manual (hiện là ấn bản thứ 5) đã được tôi đi để tham khảo từ cuối những năm 80, nhưng ngay cả khi nó có lỗi nhỏ.

Các vấn đề liên quan