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