Như được đề cập bởi những câu trả lời khác NULL
không hợp lệ để vượt qua để sscanf
như một tham số bổ sung.
http://www.cplusplus.com/reference/cstdio/sscanf nói về lý luận thêm:
Tùy thuộc vào chuỗi định dạng, chức năng có thể mong đợi một chuỗi các đối số bổ sung, mỗi có chứa một con trỏ để lưu trữ phân bổ nơi việc giải thích của các nhân vật được chiết xuất được lưu trữ với loại thích hợp.
For the %s
specifier these extracted characters are:
Bất kỳ số lượng ký tự không phải khoảng trắng, dừng tại ký tự khoảng trắng đầu tiên được tìm thấy. Một ký tự null kết thúc được tự động thêm vào cuối chuỗi được lưu trữ.
Vì vậy, khi "ký tự khoảng trắng" và "ký tự không kết thúc" được lưu trữ, sẽ có một khoảng cách. Đó là chính xác những gì Visual Studio sẽ mang lại (bạn có thể kiểm tra điều này không thành công ở http://webcompiler.cloudapp.net/):
Bây giờ như xa như phi Visual Studio biên dịch, mã khai thác libc cho các %s
specifier: https://github.com/ffainelli/uClibc/blob/master/libc/stdio/_scanf.c#L1376 có hàng đầu chú thích: /* We might have to handle the allocation ourselves */
điều này là do:
Thư viện GNU C hỗ trợ trình chỉ định chuyển đổi phân bổ động (như phần mở rộng không chuẩn) qua ký tự a
. Tính năng này dường như có mặt ít nhất là xa như glibc 2.0.
Kể từ phiên bản 2.7, glibc cũng cung cấp công cụ sửa đổi m
cho cùng mục đích với công cụ sửa đổi a
.
[Source]
Vì vậy, vì chiết xuất libc đến một bộ đệm xây dựng trong nội bộ để sscanf
và sau đó kiểm tra rằng các tham số đệm không có lá cờ thiết lập trước khi gán cho nó, nó sẽ không bao giờ viết các ký tự vào một tham số NULL
đệm.
Tôi không thể nhấn mạnh rằng đây không phải là tiêu chuẩn và không được bảo đảm để được giữ nguyên ngay cả khi cập nhật thư viện nhỏ. Cách tốt hơn để thực hiện việc này là sử dụng thông số phụ *
mà:
Cho biết dữ liệu sẽ được đọc từ luồng nhưng bị bỏ qua (tức là dữ liệu không được lưu trữ ở vị trí được chỉ định bởi đối số) .
[Source]
Điều này có thể được thực hiện như thế này ví dụ:
s == NULL ? sscanf("Privjet mir!", "%*s") : sscanf("Privjet mir!", "%s", s);
Rõ ràng là đúng ngành của ternary là một không-op, nhưng tôi đã bao gồm nó với kỳ vọng rằng các dữ liệu khác được dự kiến sẽ được đọc từ chuỗi.
Câu trả lời này cũng dạy chúng tôi rằng cấm null không cần phải đề cập đến từ "null" một cách rõ ràng.Nói rằng một cái gì đó phải là "một con trỏ đến" hoàn toàn cấm null. –
Lii