Kompiluje się, ponieważ printf
nie jest bezpieczny dla typów, ponieważ używa argumentów zmiennych w sensie C 1 . printf
nie 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::string
obsł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::string
aby 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 %d
znaczenie 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.