Он компилируется, потому что 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. Если вы лжете о типе или числе, функция не имеет стандартного способа узнать, хотя некоторые компиляторы имеют возможность проверять и выдавать предупреждения, когда вы лжете.