Він компілюється, оскільки printf
не є безпечним для типу, оскільки використовує змінні аргументи в сенсі С 1 . printf
не має можливості для std::string
, лише рядок у стилі C. Використання чогось іншого замість того, що він очікує, безумовно, не дасть вам бажаних результатів. Це фактично невизначена поведінка, тож взагалі може статися все.
Найпростіший спосіб виправити це, оскільки ви використовуєте C ++, це друкувати його звичайно std::cout
, оскільки це std::string
підтримує через перевантаження оператора:
std::cout << "Follow this command: " << myString;
Якщо з якихось причин вам потрібно витягнути рядок у стилі C, ви можете скористатися c_str()
методом, std::string
щоб отримати значення, const char *
яке недійсне. Використовуючи свій приклад:
#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;
}
Якщо ви хочете функцію, яка подобається printf
, але вводити безпеку, загляньте у різні шаблони (C ++ 11, що підтримується у всіх основних компіляторах, як у MSVC12). Приклад одного ви можете знайти тут . У стандартній бібліотеці я нічого не знаю подібного, але може бути, зокрема, в Boost boost::format
.
[1]: Це означає, що ви можете передавати будь-яку кількість аргументів, але функція покладається на вас, щоб повідомити йому кількість та типи цих аргументів. У випадку printf
, це означає рядок з кодованою інформацією типу типу %d
значення int
. Якщо ви брешите про тип або число, функція не має стандартного способу пізнання, хоча деякі компілятори мають можливість перевіряти і видавати попередження, коли ви брешите.