Kompiluje się, ponieważ printfnie jest bezpieczny dla typów, ponieważ używa argumentów zmiennych w sensie C 1 . printfnie ma opcji dla std::string, tylko łańcuch w stylu C. Używanie czegoś innego zamiast tego, czego się oczekuje, z pewnością nie przyniesie oczekiwanych rezultatów. To właściwie nieokreślone zachowanie, więc wszystko może się zdarzyć.
Najłatwiejszym sposobem rozwiązania tego problemu, ponieważ używasz C ++, jest wydrukowanie go normalnie std::cout, ponieważ std::stringobsługuje to poprzez przeciążenie operatorów:
std::cout << "Follow this command: " << myString;
Jeśli z jakiegoś powodu musisz wyodrębnić napis w stylu C, możesz użyć c_str()metody of, std::stringaby uzyskać ciąg const char *zakończony znakiem null. Na podstawie twojego przykładu:
#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;
}
Jeśli potrzebujesz funkcji, która jest podobna printf, ale bezpieczna, spójrz na różne szablony (C ++ 11, obsługiwane we wszystkich głównych kompilatorach od MSVC12). Możesz znaleźć przykład jednego tutaj . Nie ma nic, co wiem o takiej implementacji w standardowej bibliotece, ale konkretnie może istnieć w Boost boost::format.
[1]: Oznacza to, że możesz przekazać dowolną liczbę argumentów, ale funkcja polega na tym, że podasz jej liczbę i typy tych argumentów. W przypadku printf, oznacza to ciąg z zakodowanymi informacjami o typie, takimi jak %dznaczenie int. Jeśli kłamiesz na temat typu lub liczby, funkcja nie ma standardowego sposobu poznania, chociaż niektóre kompilatory mają możliwość sprawdzania i ostrzegania, gdy kłamiesz.