Nó đang biên dịch vì printf
không phải là loại an toàn, vì nó sử dụng các đối số biến theo nghĩa C 1 . printf
không có tùy chọn cho std::string
, chỉ có một chuỗi kiểu C. Sử dụng một cái gì đó khác thay cho những gì nó mong đợi chắc chắn sẽ không mang lại cho bạn kết quả như bạn muốn. Đó thực sự là hành vi không xác định, vì vậy bất cứ điều gì cũng có thể xảy ra.
Cách dễ nhất để khắc phục điều này, vì bạn đang sử dụng C ++, là in bình thường std::cout
, vì std::string
hỗ trợ điều đó thông qua quá tải toán tử:
std::cout << "Follow this command: " << myString;
Nếu, vì một số lý do, bạn cần trích xuất chuỗi kiểu C, bạn có thể sử dụng c_str()
phương thức std::string
để lấy một const char *
chuỗi kết thúc bằng null. Sử dụng ví dụ của bạn:
#include <iostream>
#include <string>
#include <stdio.h>
int main()
{
using namespace std;
string myString = "Press ENTER to quit program!";
cout << "Come up and C++ me some time." << endl;
printf("Follow this command: %s", myString.c_str()); //note the use of c_str
cin.get();
return 0;
}
Nếu bạn muốn một hàm giống như thế printf
, nhưng gõ an toàn, hãy xem các mẫu biến đổi (C ++ 11, được hỗ trợ trên tất cả các trình biên dịch chính kể từ MSVC12). Bạn có thể tìm thấy một ví dụ về một ở đây . Không có gì tôi biết được thực hiện như thế trong thư viện tiêu chuẩn, nhưng cụ thể có thể có trong Boost boost::format
.
[1]: Điều này có nghĩa là bạn có thể vượt qua bất kỳ số lượng đối số nào, nhưng hàm dựa vào bạn để cho nó biết số lượng và loại của các đối số đó. Trong trường hợp printf
, điều đó có nghĩa là một chuỗi với thông tin loại được mã hóa như %d
ý nghĩa int
. Nếu bạn nói dối về loại hoặc số, hàm không có cách nhận biết chuẩn, mặc dù một số trình biên dịch có khả năng kiểm tra và đưa ra cảnh báo khi bạn nói dối.