c++ - printf 与 std::string?

标签 c++ string namespaces printf std

我的理解是stringstd命名空间的成员,那么为什么会出现以下情况呢?

#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;
}

enter image description here

程序每次运行时,myString 都会打印一个看似随机的 3 个字符的字符串,例如上面的输出。

最佳答案

它正在编译,因为 printf不是类型安全的,因为它使用 C 意义上的可变参数1printf没有 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 起在所有主要编译器上都支持)。您可以找到一个 here 的示例.我知道在标准库中没有这样的实现,但在 Boost 中可能有,特别是 boost::format .


[1]:这意味着你可以传递任意数量的参数,但函数依赖于你告诉它这些参数的数量和类型。在 printf 的情况下,这意味着带有编码类型信息的字符串,如 %d含义 int .如果你对类型或数字撒谎,该函数没有标准的获知方式,尽管一些编译器能够在你撒谎时检查并发出警告。

关于c++ - printf 与 std::string?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10865957/

相关文章:

c++ - 使用#line 控件时调试器的奇怪行为

java - 如何检测和删除 URL 中的一句话?

C: S_ISDIR 无法正常工作,只有 "."和 ".."显示为目录

c++ - LLVM 编译器 2.0 : Warning with "using namespace std;"

c++ - IOCP:如果操作立即错误返回,我还能收到完成通知吗?

c++ - 如何在复合类型上使用 Boost.Bind?

C++:模板问题 (C2064)

java - 将两个字符串与新行合并

namespaces - 租户和命名空间之间的概念区别是什么

.net - .NET 中的全局导入/使用别名