2010-12-11 43 views
37

tôi muốn loại bỏ các cảnh báo mà tôi nhận được trên dòng này của mã này,cảnh báo: định dạng không phải là một chuỗi chữ và không có đối số định dạng

FILE *fil; 
char *imp; 
(...) 
fprintf(fil,imp); 

vấn đề là khi tôi làm điều này nó viết vào file chính xác những gì tôi muốn, nhưng nếu tôi áp dụng các định dạng% s không, như thế này

fprintf(fil, "%s", imp); 
+0

không 'imp' chứa gì? – casablanca

+1

Điều gì sẽ xảy ra nếu bạn thay thế fprintf bằng 'fputs (imp, fil);'? – pmg

+0

một chuỗi, cho phép giả sử một cái gì đó như thế này imp = "test"; – Unzi

Trả lời

43

Cảnh báo này là cách của gcc cho bạn biết rằng nó không thể xác minh đối số chuỗi định dạng cho hàm kiểu printf (printf, fprintf ... v.v.). Cảnh báo này được tạo ra khi trình biên dịch không thể tự nhìn vào chuỗi và đảm bảo rằng mọi thứ sẽ diễn ra theo ý bạn trong suốt thời gian chạy. Hãy xem xét một vài ví dụ.

Trường hợp 1. Chuỗi này có thể được xác nhận tại thời gian biên dịch và trình biên dịch sẽ cho phép nó mà không có cảnh báo:

printf("This string has no format"); 

Trường hợp 2: Đối với trường hợp này, trình biên dịch có thể phát hiện rằng bạn có một định dạng specifier và sẽ nâng cao một cảnh báo khác nhau. Trên máy của tôi, nó nói "cảnh báo: quá ít đối số cho định dạng".

// This will most probably crash your machine 
printf("Not a safe string to %s"); 

Trường hợp 3. Bây giờ điều này là hơi trường hợp của bạn. Bạn đang lấy một chuỗi được tạo ra khi chạy và cố in nó. Cảnh báo bạn nhận được là trình biên dịch cảnh báo bạn rằng có thể có một trình định dạng định dạng trong chuỗi. Nói ví dụ: "bad% sdata". Trong trường hợp này, thời gian chạy sẽ cố gắng truy cập một đối số không tồn tại để khớp với% s. Thậm chí tệ hơn, điều này có thể là một người dùng đang cố gắng khai thác chương trình của bạn (khiến nó đọc dữ liệu không an toàn để đọc).

char str[200]; 
scanf("%s", str) 
printf(str) 
+0

Gọi một hàm mà dự kiến ​​'const char *' và cho nó một 'char *' sẽ không gây ra cảnh báo, IMHO – terminus

+0

Tôi đã không gợi ý rằng chuỗi được đúc thành const. Tôi đã đề cập rằng đối số thứ hai cần phải được chỉ định để khắc phục cảnh báo. –

+0

Bạn có ý gì khi phải "chỉ định một đối số"? – UncleBens

14

trong khi về mặt kỹ thuật không có gì sai với gọi một hàm printf giống như với một chuỗi, nó vẫn là thực tế xấu vì chuỗi có thể chứa mã thông báo định dạng như %s. Ví dụ: nếu imp%s test thì những điều xấu sẽ xảy ra.

Nếu bạn chỉ muốn in imp mà không có định dạng, bạn nên sử dụng fputs(imp, fil) (lưu ý đối số được đảo ngược).

+8

Thậm chí tệ hơn: nếu người dùng có thể chỉ định chuỗi imp, anh ta có thể sử dụng mã định dạng% n để ghi đè lên bộ nhớ. Điều này được gọi là tấn công chuỗi định dạng và có thể được sử dụng để chạy mã được tiêm. – ollb

+3

fputs thực hiện thủ thuật để viết ra một chuỗi sans% định dạng. –

+0

Bạn có ý nghĩa gì với định dạng "sans%"? – TheRookierLearner

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