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
答案 0 :(得分:17)
在标准sprintf()
函数(以及其他printf()
- 类函数)中,%s
说明符不适用于C ++ strings
;它只适用于C风格的字符串。试试_UserDir.c_str()
,它会为const char *
指向string
的内部数组,因此可以与许多C函数一起使用。
如果current_path()
返回的内容不是指向const
或char
的指针(可能是unsigned char
),则还需要转换该值。
答案 1 :(得分:3)
string
实际上是std::string
吗? path
一个boost::filesystem::path
?在这种情况下,您应该知道C库函数(如sprintf
和printf
)不支持像std::string
这样的C ++类。那是很自然的。
您需要做的是:
sprintf(filebuf, "%s%s", current.c_str(), _UserDir.c_str());
但是,如果您已经在使用C ++,那么更优雅的解决方案是使用std::stringstream
或boost::format
。作为奖励,不必在堆栈上分配缓冲区,并担心结果可能比缓冲区更长(这可能导致缓冲区溢出和安全漏洞 - sprintf()
可能是其中许多人的罪魁祸首...)。
<强>的std :: stringstream的强>
std::stringstream filebuf;
filebuf << current_path().c_str() << _UserDir;
std::string filename = filebuf.str();
<强>升压::格式强>
std::string filename = "%s%s" % current_path().c_str() % _UserDir;
顺便说一下,如果你只想连接目录,那么boost::filesystem::path
的“正确”方法就是:
boost::filesystem::path fullPath = current_path() / _UserDir;
是的,/
运算符用于添加路径组件。毕竟它们是用斜线分隔的,不是吗?
话虽如此,如果您仍然选择使用旧的C库函数,而不是使用旧的C库函数,请为此,请使用sprintf()
。使用稍微更安全的snprintf(),它将最大缓冲区大小作为参数。
答案 2 :(得分:1)
你的一些代码不清楚(例如,究竟是path
类型是什么?),但看起来你正试图通过std::string
来打印一个C风格的字符串格式化程序(sprintf %s
),它完全无效。
看看std::stringstream
。此外,对于简单连接,std::string
提供+
运算符重载。所以你可以做的很简单:
current + "/" + whatever
答案 3 :(得分:1)
sprintf仅适用于char *,不能将其与字符串一起使用。试试_UserDir.c_str(),你应该没问题。
答案 4 :(得分:1)
我不明白为什么你的编译器没有抱怨。您不能将非{POD类型,例如std::string
或boost::filepath
作为varargs传递;我的编译器说这会在运行时中止,并且任何编译器都会在这里知道你将类类型传递给vararg。 (形式上,它是未定义的行为,但除非编译器以某种方式将其定义为扩展,否则没有理由不至少警告它。)
答案 5 :(得分:0)
当前不是char *指针,它是一个路径,因此可能导致复杂化
另外,sprintf无法像你想要的那样打印到字符串变量。
答案 6 :(得分:0)
current_path
多长时间?也许是strlen(current_path)+strlen(_UserDir)+2 > 256
。
答案 7 :(得分:0)
由于_UserDir
是C ++ string
,因此您需要获取其C字符串以调用{C}函数sprintf()
。
sprintf(filebuf,"%s/%s",current,_UserDir.c_str()); // gets C string
另外,什么是path
?如果它与typedef
的{{1}}不同,那么您也不能只char*
。可能sprintf()
的{{1}}超载,这就是operator<<()
的原因。
答案 8 :(得分:0)
%s
表示C字符串。你有一个C ++字符串。您需要致电.c_str()
答案 9 :(得分:0)
崩溃的原因已经解释了 - 我只能添加一条建议 - 如果可能的话,只需抛弃sprintf并使用字符串流。它会让你的代码变得更好。您不必担心缓冲区的长度或其他错误,例如您遇到的错误。