为什么这个sprint语句崩溃了

Why this sprintf statement crashing?

本文关键字:崩溃 语句 sprint 为什么      更新时间:2023-10-16
char filebuf[256];
path current = current_path();
std::cout<<"CurrentWorking "<<current<<endl;
string _UserDir = "TTiTraceLogs";
sprintf(filebuf,"%s/%s",current,_UserDir); ///crashing here

如果我只格式化current,那么就可以了。

sprintf(filebuf,"%s",current);
输出:

CurrentWorking D:/working/eclipse_projects/sadftp/CollectTTiTraceSept10_1009_174
_higher/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/Release

在标准sprintf()函数(和其他printf()类函数)中,%s指示符不能与c++ strings一起工作;它只适用于c风格的字符串。试试_UserDir.c_str(),它给你一个指向string内部数组的const char *,因此可以与许多C函数一起使用。

如果current_path()返回的不是指向charunsigned char的指针(可能是const),您也需要转换该值

string实际上是std::string吗?pathboost::filesystem::path ?在这种情况下,您应该知道C库函数(如sprintfprintf)不支持像std::string这样的c++类。这是很自然的。

你需要做的是:

sprintf(filebuf, "%s%s", current.c_str(), _UserDir.c_str());

但是一个更优雅的解决方案,如果你已经在使用c++,是使用std::stringstreamboost::format。作为奖励,它不必在堆栈上分配缓冲区,也不必担心结果可能比缓冲区长(这可能导致缓冲区溢出和安全漏洞——sprintf()可能是许多问题背后的罪魁祸首……)。

std:: stringstream

std::stringstream filebuf;
filebuf << current_path().c_str() << _UserDir;
std::string filename = filebuf.str();
boost::格式

std::string filename = "%s%s" % current_path().c_str() % _UserDir;
顺便说一下,如果你只是想连接目录,使用boost::filesystem::path的"正确"方法是:
boost::filesystem::path fullPath = current_path() / _UserDir;

是,/操作符用于添加路径组件。毕竟它们是用斜杠隔开的,不是吗?

也就是说,如果你仍然不顾所有好的建议,选择使用旧的C库函数,请不要使用sprintf()。使用稍微安全一点的snprintf(),它将最大缓冲区大小作为参数。

您的一些代码不清楚(例如:path类型到底是什么?),但看起来你试图通过c风格的字符串格式化器(sprintf %s)打印std::string,这是完全无效的。

std::stringstream。此外,对于简单的连接,std::string提供了+操作符重载。所以你可以简单地这样做:

current + "/" + whatever

sprintf只适用于char*,不能用于字符串。试试_UserDir.c_str(),应该没问题。

我不明白的是为什么你的编译器没有抱怨。您不能将std::stringboost::filepath等非pod类型作为变量传递;我的编译器说这将在运行时中止,任何编译器都会知道你正在将类类型传递给变量。(形式上,这是未定义的行为,但除非编译器以某种方式将其定义为扩展,否则它没有理由不发出警告。)

current不是一个char*指针,它是一个路径,所以它可能会导致复杂性

还有,sprintf不能像你想做的那样打印到字符串变量

current_path有多长?可能是strlen(current_path)+strlen(_UserDir)+2 > 256 .

由于_UserDir是c++ string,您需要获得它的C字符串来调用sprintf(),这是一个C函数。

sprintf(filebuf,"%s/%s",current,_UserDir.c_str());  // gets C string

还有,什么是path ?如果它不像char*typedef,那么你也不能只sprintf()。这可能是operator<<()path过载,这就是std::cout工作的原因。

%s表示C字符串。你有一个c++字符串。您需要调用.c_str()

崩溃的原因已经解释过了——我只能添加一条建议——如果可能的话放弃sprintf,使用字符串流。它将使你的代码更好。您不必担心缓冲区的长度或遇到的其他错误。