c – sprintf如何与CString和std :: string一起使用

前端之家收集整理的这篇文章主要介绍了c – sprintf如何与CString和std :: string一起使用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
CString s = "test";
std::string ss = "test";

char z[100];
sprintf(z,"%s",ss.c_str()); // z = "test"  : OK

char z2[100];
sprintf(z2,ss); // z2 = "(null)" : OK. undefined behavior is expected

char z3[100];
sprintf(z3,s); // z3 = "test" : How is this possible ?!

任何人都可以解释CString如何与sprintf正常工作?

解决方法

它的工作原理是因为CString类的第一个元素是一个指向char数组的指针.实际上,CString中唯一的字段是指向字符串数组的指针.这个类使用一些技巧来隐藏内部数据(如字符串长度,保留缓冲区大小等),方法是分配一个大缓冲区,然后将唯一的类指针指向char数组,以获取那些内部数据字段,它通过已知的方式移动此指针偏移.

你应该做的是调用s.GetBuffer(0);或(LPCTSTR)s;但用它作为

sprintf(z2,ss);

被MFC创建者设计允许,当然它可以在Windows下在其他平台上运行,它可能会崩溃.

[评论后编辑]

你的代码将更安全,如果不是像(LPCTSTR)那样的c风格的演员表,你将使用c cast:static_cast< LPCTSTR>(s);.但是很快你就会发现你的代码在所有这些static_cast-s中都很难看,特别是如果你的sprintf-s有很多参数的话.这是我记忆(在我看来)的设计,c风格的演员表旨在让你重新考虑你的设计,根本不使用演员表.在你的情况下,你应该使用std :: wstringstream而不是使用sprintf(假设你使用UNICODE构建):

#include<sstream>

std::wostream & operator<< (std::wostream &out,CString const &s) {
  out << s.GetString();
  return out;
}

int main(){
  CString s = _T("test");
  std::wstringstream ss;
  ss << s;  // no cast required,no UB here
  std::wcout << ss.str();
  return 0;
}

猜你在找的C&C++相关文章