The*_*978 144 c++ string printf namespaces std
我的理解是它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;
}
Run Code Online (Sandbox Code Playgroud)
每次程序运行时,都会myString
打印一个看似随机的3个字符的字符串,例如上面的输出.
chr*_*ris 218
它正在编译,因为printf
它不是类型安全的,因为它在C意义1中使用变量参数.printf
没有选项std::string
,只有C风格的字符串.用其他东西代替它所期望的东西肯定不会给你想要的结果.它实际上是未定义的行为,因此任何事情都可能发生.
解决这个问题的最简单方法是,因为你正在使用C++,所以正常打印它std::cout
,因为std::string
通过运算符重载支持:
std::cout << "Follow this command: " << myString;
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因,您需要提取C样式字符串,则可以使用c_str()
方法std::string
获取以const char *
null结尾的方法.使用你的例子:
#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;
}
Run Code Online (Sandbox Code Playgroud)
如果你想要一个类似printf
但是类型安全的函数,请查看可变参数模板(C++ 11,从MSVC12开始支持所有主要编译器).你可以在这里找到一个例子.我知道在标准库中没有像这样的实现,但可能在Boost中,特别是boost::format
.
[1]:这意味着您可以传递任意数量的参数,但函数依赖于您告诉它这些参数的数量和类型.在这种情况下printf
,这意味着具有编码类型信息的字符串,如%d
含义int
.如果你撒谎的类型或数字,该功能没有标准的知道方式,虽然有些编译器能够检查并在你撒谎时发出警告.
Jer*_*fin 40
请不要使用 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;
Run Code Online (Sandbox Code Playgroud)
无名语言环境("")根据用户的配置选择语言环境.因此,在我的机器上(配置为美国英语)打印出来123,456.78
.对于那些为(例如)德国配置计算机的人来说,它会打印出类似的东西123.456,78
.对于那些为印度配置它的人来说,它会打印出来1,23,456.78
(当然还有很多其他的).随着printf
我得到完全一个结果:123456.78
.这是一致的,但对所有人来说都是错误的.基本上解决它的唯一方法是单独进行格式化,然后将结果作为字符串传递给printf
,因为printf
它本身根本无法正常工作.
printf
格式字符串可能非常难以理解.即使在printf
几乎每天都在使用的C程序员中,我猜想至少有99%的人需要仔细研究以确定其中#
的%#x
含义,以及它与其中#
的%#f
含义有何不同(是的,它们意味着完全不同的东西) ).使用std :: printf和c_str()示例:
std::printf("Follow this command: %s", myString.c_str());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
318317 次 |
最近记录: |