C++:C 字符串到 std:string
C++: C string to std:string
我正在尝试使用函数将 C 字符串转换为 std::string。该函数在 64 位 gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9)
上正常工作。但是当我用 -O2
或 -O3
优化编译它时,它会出现段错误。它适用于 -O1
不过。有人可以建议修复或解决这个问题吗?函数如下:
void make_name(unsigned const &i, string &h_file)
{
char h_str[10];
sprintf(h_str, "tmp/%09d.hb", i);
h_file = string(h_str);
}
简单:提供足够的缓冲。或者使用 std::stringstream
。
char h_str[10];
sprintf(h_str, "tmp/%09d.hb", i);
这是未定义的行为。您正在尝试将大约 17 个字节的数据写入一个 10 字节的数组:
tmp/
是四。
%09d
将至少扩展到九个。
.hd
是三.
- 字符串终止符
[=15=]
是一个。
不要那样做。未定义的行为意味着所有功能保证都是无效的。
事实上,如果你想成为一个真正体面的 C++ 开发人员,你应该尽可能地避免遗留的东西。
学习和库代码都很好,需要 运行 在 C 和 C++ 中。但是,对于 C++ 代码,使用该语言的非遗留部分要健壮得多。
下面的程序展示了如何做到这一点而不必恢复到cstdio/stdio.h
中的遗留 C 语言:
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
void make_name (unsigned int i, string &h_file) {
stringstream ss;
ss << "tmp/" << setw(9) << setfill('0') << i << ".hb";
h_file = ss.str();
}
int main() {
string s;
make_name (42u, s);
cout << s << '\n';
return 0;
}
As an aside, you'll see I've changed your method signature to pass i
by value. That's because I'm not sure there's any advantage to doing it as a const
reference. Feel free to change it back if you do find an advantage.
最好永远不要使用 C 字符串。
std::string make_name(unsigned i)
{
std::ostringstream str;
str << "tmp/" << std::setfill('0') << std::setw(9) << i << ".hb";
return std::move(str.str());
}
我正在尝试使用函数将 C 字符串转换为 std::string。该函数在 64 位 gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9)
上正常工作。但是当我用 -O2
或 -O3
优化编译它时,它会出现段错误。它适用于 -O1
不过。有人可以建议修复或解决这个问题吗?函数如下:
void make_name(unsigned const &i, string &h_file)
{
char h_str[10];
sprintf(h_str, "tmp/%09d.hb", i);
h_file = string(h_str);
}
简单:提供足够的缓冲。或者使用 std::stringstream
。
char h_str[10];
sprintf(h_str, "tmp/%09d.hb", i);
这是未定义的行为。您正在尝试将大约 17 个字节的数据写入一个 10 字节的数组:
tmp/
是四。%09d
将至少扩展到九个。.hd
是三.- 字符串终止符
[=15=]
是一个。
不要那样做。未定义的行为意味着所有功能保证都是无效的。
事实上,如果你想成为一个真正体面的 C++ 开发人员,你应该尽可能地避免遗留的东西。
学习和库代码都很好,需要 运行 在 C 和 C++ 中。但是,对于 C++ 代码,使用该语言的非遗留部分要健壮得多。
下面的程序展示了如何做到这一点而不必恢复到cstdio/stdio.h
中的遗留 C 语言:
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
void make_name (unsigned int i, string &h_file) {
stringstream ss;
ss << "tmp/" << setw(9) << setfill('0') << i << ".hb";
h_file = ss.str();
}
int main() {
string s;
make_name (42u, s);
cout << s << '\n';
return 0;
}
As an aside, you'll see I've changed your method signature to pass
i
by value. That's because I'm not sure there's any advantage to doing it as aconst
reference. Feel free to change it back if you do find an advantage.
最好永远不要使用 C 字符串。
std::string make_name(unsigned i)
{
std::ostringstream str;
str << "tmp/" << std::setfill('0') << std::setw(9) << i << ".hb";
return std::move(str.str());
}