2010-11-20 27 views
14

Chương trình của tôi như sau;Tại sao việc sử dụng trình định dạng sai trong C làm hỏng chương trình của tôi trên Windows 7?

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

int main() 
{ 
     char string[] = "Gentlemen start your engines!"; 
     printf("That string is %s characters long.\r\n", strlen(string)); 
     return 0; 
} 

Tôi đang biên soạn dưới gcc và mặc dù nó không cho tôi bất kỳ lỗi nào chương trình gặp sự cố mỗi khi tôi chạy. Mã này có vẻ là tốt đẹp từ các ví dụ tôi đã nhìn thấy. Thật tuyệt khi biết tôi có làm gì sai không.

Cảm ơn.

+0

Cảm ơn mọi người. Nên đã thấy rằng, tôi vừa mới bắt đầu với C và đã được chơi xung quanh với các chương trình văn bản bằng cách sử dụng dây chỉ cho đến nay, vì vậy% s chỉ tự động đến tâm trí. – austinprete

+4

+1 vì tôi biết rằng tôi nên sử dụng% zu cùng với thay vì chỉ% u hoặc thậm chí% d –

+1

Nếu bạn đang sử dụng GCC, hãy sửa lỗi của bạn bằng '-Wall' hoặc có thể' -Wextra' hoặc có thể '-Werror'. GCC có thể kiểm tra chuỗi định dạng và cảnh báo về các đối số không chính xác cho các hàm 'printf'-,' scanf'-, 'strftime'- và' strfmon'. –

Trả lời

16

Sử dụng format specifier không chính xác trong printf() gọi hành vi undefined. Đúng format specifier nên %zu (không %d) vì kiểu trả về của strlen()size_t

Lưu ý: Chiều dài modifier z trong %zu đại diện cho một số nguyên có độ dài tương tự như size_t

+0

Khi nào gcc trên Windows ngừng sử dụng Microsoft CRT? Tôi đã nhận được lỗi lần cuối cùng tôi đã sử dụng% zu trên MinGW hoặc có phiên bản gcc khác sử dụng glib không? –

+0

@Pete: Bạn không nên nhận được bất kỳ lỗi nào như vậy. Đảm bảo bạn đang sử dụng phiên bản mới nhất của MinGW có hỗ trợ C99. –

+0

Ngọt ngào! Bất kỳ ETA nào cho MingW thực thi miền địa phương UTF-8 mô phỏng trên các chức năng '_wfopen' của windows? –

2
printf("That string is %d characters long.\r\n", strlen(string)); 

thay vì:

printf("That string is %s characters long.\r\n", strlen(string)); 
+0

một morething, thay đổi tên biến "chuỗi" để someother. "string" là từ dành riêng. –

+0

Ok, cảm ơn.Tôi đã sử dụng 'string' để kết hợp một chương trình nhanh có độ dài chuỗi, khi tôi viết một chương trình phát hiện palindromes và muốn có cảm giác về cách tôi làm điều đó. Tôi sẽ ghi nhớ không sử dụng nó trong tương lai. – austinprete

+0

Cú pháp, 'chuỗi' không phải là một từ khóa. Mặc dù, tất cả các tên đều bắt đầu bằng 'str',' mem' hoặc 'wcs'," dành cho sử dụng trong tương lai "như một hàm chuỗi trong tiêu đề' '. (nguồn: ISO C99, 7.26.11) –

7

Bạn có specifier định dạng sai. %s được sử dụng cho chuỗi nhưng bạn đang đi qua size_t (strlen(string)). Sử dụng thông số định dạng không đúng trong printf() gọi hành vi không xác định. Sử dụng %zu thay vì loại trả lại là strlen()size_t.

Vì vậy, thay đổi

printf("That string is %s characters long.\r\n", strlen(string)); 

tới:

printf("That string is %zu characters long.\r\n", strlen(string)); 

Vì bạn đang sử dụng gcc có một cái nhìn here để biết thêm những gì có thể được chuyển tới printf

+1

Sử dụng 'gcc' để biên dịch không nhất thiết có nghĩa là bạn đang sử dụng glibc để thực thi mã của mình. –

2

Bạn có một vấn đề ở đây printf("That string is %s characters long.\r\n", strlen(string));

đặt

printf("That string is %d characters long.\r\n", strlen(string)); % d bởi vì bạn muốn printthe chiều dài của str (strlen lợi nhuận số)

1

tai nạn Chương trình vì định dạng cố gắng thường xuyên truy cập vào một chuỗi tại địa chỉ 0x0000001D mà là kết quả của strlen() nơi là gì giống như một chuỗi và có khả năng không có bộ nhớ acessible nào cả.

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