2012-01-18 102 views
5

Tôi có một câu hỏi liên quan đến fgets và fscanf trong C. chính xác là sự khác biệt giữa hai? Ví dụ:Sự khác biệt giữa fgets và fscanf?

char str[10]; 
while(fgets(str,10,ptr)) 
{ 
counter++; 
... 

và ví dụ thứ hai:

char str[10]; 
while(fscanf(ptr,"%s",str)) 
{ 
counter++; 
... 

khi có một file văn bản chứa chuỗi được phân cách bởi một khoảng trống, ví dụ: AB1234 AC5423 AS1433. Trong ví dụ đầu tiên, "bộ đếm" trong vòng lặp while sẽ không đưa ra cùng một đầu ra như trong ví dụ thứ hai. Khi thay đổi "10" trong chức năng fgets, bộ đếm sẽ luôn cho kết quả khác nhau. Lý do cho điều này là gì? Ai đó cũng có thể giải thích chính xác fscanf làm gì, chuỗi dài trong mỗi vòng lặp trong bao lâu?

Trả lời

5

Chức năng fgets đọc cho đến khi một dòng mới (và cũng lưu trữ nó). fscanf với thông số %s đọc cho đến khi có bất kỳ khoảng trống nào và không lưu trữ ...

Lưu ý phụ, bạn không chỉ định kích thước của bộ đệm trong scanf và không an toàn. Thử:

fscanf(ptr, "%9s", str) 
+0

Cảm ơn câu trả lời của bạn, điều này cũng tương tự cho fput và fprintf? Hay sự khác biệt giữa chúng là gì? – phpheini

+0

Không, chúng khác nhau. Ví dụ '% s' không dừng ở khoảng trống trong printf. Đọc hướng dẫn. – cnicutar

3

fgets đọc đến dòng mới. fscanf chỉ đọc tối đa khoảng trắng.

1

fgets đọc toàn bộ dòng. fscanf với %s đọc một chuỗi, tách biệt bằng dấu cách (hoặc \ n, \ t, v.v ...). Dù sao, bạn không nên sử dụng chúng trừ khi bạn chắc chắn rằng mảng bạn đọc là đủ lớn để chứa đầu vào. Bạn đã viết When changing the "10" in the fgets function the counter will always give different results. Lưu ý rằng fgets và scanf không biết số byte cần đọc. bạn nên nói với họ. thay đổi "10" chỉ cần mở rộng bộ đệm các chức năng này ghi vào.

1

Trong ví dụ của bạn, fgets sẽ đọc tối đa 9 ký tự từ luồng đầu vào và lưu chúng vào str, cùng với một 0 terminator. Nó sẽ không bỏ qua khoảng trắng hàng đầu. Nó sẽ dừng lại nếu nó thấy một dòng mới (sẽ được lưu vào str) hoặc EOF trước số ký tự tối đa.

fscanf với %s trình chỉ định chuyển đổi sẽ bỏ qua bất kỳ khoảng trống phía trước nào, sau đó đọc tất cả các ký tự không khoảng trắng, lưu chúng vào str theo sau là một 0 terminator. Nó sẽ dừng đọc ở ký tự khoảng trống tiếp theo hoặc EOF. Nếu không có chiều rộng trường rõ ràng, nó sẽ đọc nhiều ký tự không phải khoảng trắng như trong luồng, có khả năng tràn bộ đệm đích.

Vì vậy, hãy tưởng tượng luồng đầu vào trông như sau: "\t abcdef\n<EOF>". Nếu bạn đã sử dụng fgets để đọc, str sẽ chứa "\t abcdef\n\0". Nếu bạn đã sử dụng fscanf, str có thể chứa "abcdef\0" (trong đó \0 cho biết trình kết thúc 0).

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