我的理解是string
是std
命名空间的成员,那么为什么会出现以下情况呢?
#include <iostream>
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);
cin.get();
return 0;
}
每次程序运行时,mystring
都会打印一个看似随机的3个字符的字符串,如上面的输出。
之所以进行编译,是因为printf
不是类型安全的,因为它使用了C语言意义上的变量参数1。 printf
没有std::string
选项,只有C样式字符串。 用别的东西代替它所期望的东西肯定不会给你想要的结果。 这实际上是一种未定义的行为,所以任何事情都可能发生。
由于您使用的是C++,最简单的解决方法是使用std::cout
正常打印它,因为std::string
通过操作符重载支持此功能:
std::cout << "Follow this command: " << myString;
如果出于某种原因需要提取C样式字符串,可以使用std::string
的c_str()
方法来获取以空结尾的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
但类型安全的函数,请查看variadic模板(C++11,从MSVC12开始所有主要编译器都支持)。 你可以在这里找到一个例子。 我不知道在标准库中有什么类似的实现,但是在Boost中可能有,特别是Boost::format
。
[1]:这意味着您可以传递任意数量的参数,但是函数依赖于您告诉它那些参数的数量和类型。 在printf
的情况下,这意味着具有编码类型信息的字符串,例如%d
意味着int
。 如果你在类型或数字上撒谎,函数没有标准的知道方式,尽管一些编译器有能力检查并在你撒谎时给出警告。
请不要使用printf(“%s”,your_string.c_str());
使用cout<<<; 改为Your_String;
。 简短,简单和类型安全。 实际上,当您编写C++时,通常希望完全避免printf
--它是C语言中的一个剩余部分,在C++中很少需要或有用。
至于为什么要使用cout
而不是printf
,原因不胜枚举。 下面是几个最明显的例子:
>
printf
不是类型安全的。 如果您传递的类型与转换说明符中给出的类型不同,printf
将尝试使用它在堆栈上找到的任何东西,就像它是指定的类型一样,从而给出未定义的行为。 有些编译器可以在某些情况下对此发出警告,但有些编译器根本不能/不愿意发出警告,而且没有一个编译器可以在所有情况下发出警告。printf
不可扩展。 您只能向它传递基元类型。 它所理解的转换说明符集在它的实现中是硬编码的,您没有办法添加更多/其他。 大多数编写良好的C++应该主要使用这些类型来实现面向所解决问题的类型。它使适当的格式设置更加困难。 举个明显的例子,当您打印数字供人们阅读时,您通常希望每隔几个数字插入几千个分隔符。 作为分隔符使用的数字和字符的确切数目各不相同,但cout
也涵盖了这一点。 例如:
std::locale loc("");
std::cout.imbue(loc);
std::cout << 123456.78;
无名区域设置(“”)根据用户的配置选择区域设置。 因此,在我的机器上(配置为美式英语),这将打印为123,456.78
。 对于为德国配置计算机的人来说,它会打印出类似123.456,78
的内容。 对于为印度配置了它的人来说,它将输出为1,23,456.78
(当然还有很多其他的)。 使用printf
,我正好得到一个结果:123456.78
。 这是始终如一的,但对任何地方的每个人来说都是始终如一的错误。 基本上,解决它的唯一方法是单独进行格式化,然后将结果作为字符串传递给printf
,因为printf
本身并不能正确地完成这项工作。
如果希望类似C的字符串(const char*
)与printf一起使用,请使用mystring.c_str()
谢谢