Sự mơ hồ bắt đầu từ chính Tiêu chuẩn C. Cả C99 và C11 đều có mô tả snprintf
chức năng giống hệt nhau . Đây là mô tả từ C99:
7.19.6.5 snprintf
Tóm tắt hàm
1 #include <stdio.h>
int snprintf(char * restrict s, size_t n, const char * restrict format, ...);
Mô tả
2 snprintf
Hàm tương đương với fprintf
, ngoại trừ việc đầu ra được ghi vào một mảng (được chỉ định bởi đối số s
) chứ không phải vào một dòng. Nếu n
là 0, không có gì được viết và s
có thể là một con trỏ rỗng. Nếu không, các ký tự đầu ra ngoài n-1
st sẽ bị loại bỏ thay vì được ghi vào mảng và ký tự null được viết ở cuối các ký tự thực sự được ghi vào mảng. Nếu việc sao chép diễn ra giữa các đối tượng chồng lên nhau, hành vi đó là không xác định.
Trả về
3 snprintf
Hàm trả về số ký tự đã được viếtn
đủ lớn, không tính ký tự rỗng kết thúc hoặc giá trị âm nếu xảy ra lỗi mã hóa. Do đó, đầu ra kết thúc bằng null đã được ghi hoàn toàn nếu và chỉ khi giá trị trả về là không âm và nhỏ hơn n
.
Một mặt , câu
Nếu không, các ký tự đầu ra ngoài n-1
st sẽ bị loại bỏ thay vì được ghi vào mảng và ký tự null được viết ở cuối các ký tự thực sự được viết vào mảng
nói rằng
nếu (các s
trỏ đến một mảng dài 3 ký tự và) n
là 3, thì 2 ký tự sẽ được viết và các ký tự ngoài mảng thứ 2 sẽ bị loại bỏ ; thì ký tự null được viết sau 2 cái đó (và ký tự null sẽ là ký tự thứ 3 được viết) .
Và điều này tôi tin rằng trả lời câu hỏi ban đầu.
TRẢ LỜI:
Nếu việc sao chép diễn ra giữa các đối tượng chồng lên nhau, hành vi đó là không xác định.
Nếu n
là 0 thì không có gì được ghi vào đầu ra
, ngược lại nếu không gặp lỗi mã hóa, đầu ra LUÔN LUÔN kết thúc bằng rỗng ( bất kể đầu ra có phù hợp với mảng đầu ra hay không ; nếu không thì một số ký tự sẽ bị loại bỏ để đầu ra mảng không bao giờ bị tràn),
nếu không (nếu gặp lỗi mã hóa) đầu ra có thể không bị kết thúc bằng null .
Mặt khác
Câu cuối cùng
Do đó, đầu ra kết thúc bằng null đã được ghi hoàn toàn nếu và chỉ khi giá trị trả về là không âm và nhỏ hơn n
đưa ra sự mơ hồ (hoặc tiếng Anh của tôi không đủ tốt). Tôi có thể giải thích câu này theo ít nhất hai cách:
1. Kết quả đầu ra là null-end nếu và chỉ khi giá trị trả về không âm và nhỏ hơnn
(có nghĩa là nếu giá trị trả về không nhỏ hơn n
, tức là đầu ra (bao gồm kết thúc ký tự null) không phù hợp với mảng, thì đầu ra không phải là ký tự null ).
2. Kết quả hoàn tất (không có ký tự nào bị loại bỏ) nếu và chỉ khi giá trị trả về không âm và nhỏ hơnn
.
Tôi tin rằng cách giải thích 1 ở trên mâu thuẫn với CÂU TRẢ LỜI, gây ra hiểu lầm và thảo luận dài dòng. Đó là lý do tại sao câu cuối cùng mô tả snprintf
hàm cần thay đổi để loại bỏ bất kỳ sự mơ hồ nào (điều này tạo cơ sở để viết Đề xuất cho Tiêu chuẩn ngôn ngữ C).
Ví dụ về từ ngữ không mơ hồ mà tôi tin rằng có thể được lấy từ http://en.cppreference.com/w/c/io/fprintf (xem 4)
), cảm ơn @ "Martin Ba" cho liên kết.
Xem thêm câu hỏi " snprintf: Có bất kỳ Đề xuất / kế hoạch Tiêu chuẩn C nào để thay đổi mô tả của func này không? ".