微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

原文地址:https://www.jb51.cc/c/115880.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐