Tại sao tham số 'n' của snprintf bị bỏ qua?


8

Tôi đã thấy rằng ntham số snprintf()dường như bị bỏ qua trong mã của tôi.

char asdf[10];
Serial1.println(snprintf(asdf, 2, "hello"));

Điều này in 5 khi tôi mong đợi nó sẽ in 2. Điều gì đang xảy ra?


Biến asdfcó chứa "xin chào" hoặc "h" không? Nếu nó chứa "h" thì tham số không bị bỏ qua.
Nick Gammon

Câu trả lời:


7

snprintf () sẽ không viết nhiều hơn <size> (đối số 2d của snprintf) vào bộ đệm của bạn, nhưng nó sẽ tính (và loại bỏ các ký tự phụ) mà nó đã viết, đã có đủ khoảng trống và đó là số mà nó trả về . Vâng, nó có thể gây nhầm lẫn!

Xem tài liệu tham khảo snprintf () này .


5
Nó sẽ hữu ích vì bạn có thể snprintfvới một bộ đệm rất nhỏ, lưu ý số được trả về, sau đó malloclà bộ đệm có kích thước phù hợp và làm lại. Bằng cách đó bạn biết có bao nhiêu byte để phân bổ.
Nick Gammon

4
@NickGammon: Hoặc bạn có thể snprintfkhông có bất kỳ bộ đệm nào (một con trỏ đích null được mô tả rõ ràng là một đối số hợp lệ cho trường hợp Destlength == 0) khi đo chiều dài.
supercat

1
Thật. Điều đó cũng được thực hiện trong các thói quen đầu ra văn bản của Windows để đo lượng không gian mà một số văn bản trong một số phông chữ sẽ chiếm, mà không thực sự vẽ nó.
Nick Gammon

3

Một bản phác thảo thử nghiệm cho Arduino Uno:

char buffer[10];

void setup() {
  Serial.begin(9600);
  int n = snprintf(buffer, 2, "hello");
  Serial.println(n);
  Serial.println(buffer);
}

void loop() {
}

Như @JRobert đã viết, "sẽ có" là chìa khóa. Theo như tôi biết chỉ snprintfvsnprintf trả về số "sẽ có".

Tôi nghĩ lý do là để có thể biết nếu chuỗi bị cắt ngắn. Giả sử tham số 'size' là 25 và chuỗi định dạng rất dài, thì giá trị trả về có thể được kiểm tra theo 25. Nếu giá trị trả về là 26 (số byte "sẽ có"), thì chuỗi bị cắt ngắn.
Thông tin này không thể truy xuất khi số "sẽ có" không có sẵn.


2

Để hoàn thành, trang man cho fprintfcác trạng thái:

Hàm snprintf () sẽ tương đương với sprintf (), với việc thêm đối số n trong đó nêu kích thước của bộ đệm được gọi bởi s. Nếu n bằng 0, không có gì được viết và s có thể là con trỏ null. Mặt khác, các byte đầu ra ngoài n ‐ 1st sẽ bị loại bỏ thay vì được ghi vào mảng và một byte null được ghi ở cuối các byte thực sự được ghi vào mảng.

và, có liên quan hơn:

Sau khi hoàn thành thành công, hàm snprintf () sẽ trả về số byte được ghi vào s có n đủ lớn, ngoại trừ byte null kết thúc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.