将内置数据类型转换为std::string: memcpy vs snprintf
Convert built-in data type to std::string: memcpy vs snprintf
我在此之前参考了相关问题和其他帖子。我也知道std::to_string()
是最好的方式(但它在少数平台上不可用)。
当实验时,我遇到了memcpy()
的一个奇怪问题。对于示例,假设我们总是将内置数据类型(int
, char
, long
)传递给下面的函数:
template<typename T>
std::string to_string (const T& value)
{
std::string s(16, 0); // Max size captured
::memcpy(&s[0], &value, sizeof(value));
return s;
}
在示例程序中单独运行此函数可以正常工作。但是当插入更大的代码库时,不知何故它会给出奇怪的结果!也就是说,它给出了虚假的值。(Ubuntu 14.10, c++ 4.9 -std=c++11)
但是,如果我使用sprintf()
转换上面的程序,它工作得很好。
template<typename T>
std::string to_string (const T& value)
{
std::string s(16, 0); // Max size captured
s[::snprintf(&s[0], "%d", value)] = 0;
return s;
}
:
- 我触摸未定义的行为与
memcpy()
(或甚至sprintf()
) ? - 字节顺序会影响这个代码吗?
概括一下,是的,您不希望使用memcpy()
。使用snprintf()
可以避免自己将数字转换为ASCII。不过,这样的代码可能更可取:
template<typename T>
std::string to_string (const T& value)
{
char buf[16];
::snprintf(buf, sizeof(buf), "%d", value);
// ^-- size was missing in your example
return buf;
}
然而,在这个函数中有一个很大的流,因为你不知道T是什么。它可能是一个双和"%d"
不会像预期的那样工作。同样,它也可以是字符串(char const *
)。
如果您想手动将数字转换为ASCII,您可以使用循环,如下所示:
template<typename T>
std::string to_string (T value)
{
char buf[16]; // any int number is less than 16 characters
char *s = buf + sizeof(buf);
*--s = ' ';
do
{
*--s = value % 10 + '0'; // conversion to ASCII, 1 digit at a time
value /= 10;
}
while(value > 0);
return s;
}
警告:该函数不能正确处理负数。我把它作为一个练习,让你根据需要来处理。
现在,如果你想用c++的方式在你提到的所有系统上工作,没有boost或c++ 11。
template<typename T>
std::string to_string (T const& value)
{
std::stringstream ss;
ss << value;
return ss.str();
}
在这种情况下,stringstream知道如何处理T,无论T是什么,数字,对象等,只要这些东西理解<<
和std::cout << "Hello!" << std::endl;
。
如果你查看我的一个名为as2js的项目,你会看到一个名为include/as2js/node.h的文件,其中声明如下:
std::ostream& operator << (std::ostream& out, Node const& node);
这意味着您可以稍后创建一个节点并像这样打印它:
Node n;
std::out << n << std::endl;
这意味着to_string()函数将与我的Node对象一起工作。
您可以在lib/node_display.cpp
- cppcheck在const std::string[]上引发警告
- 将std::string传递给WriteConsole API
- 为std::string的某个索引赋值
- std中有类似find_last_of的函数,而string中没有
- 使用 std::string () const 函数启动线程或未来
- 使用char类型将decimal转换为string,将string转换为decimal
- 迭代和比较映射<字符串、矢量<string>> c++ 中的值
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- vector<vector<double>> to mxArray using memcpy
- 将向量解析<string>为字符串
- 'string.assign(string.data(), 5)' 是明确定义的还是 UB?
- 如何更改大小(std::string)
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- C++:如何将 unix 时间的字符串转换为 *tm?(使用时间错误:"cannot convert 'String' to 'tm*' ")
- std::string 的对象真的可以移动吗?
- 与'operator='不匹配(操作数类型'String'且"void")
- 与C-string('malloc'+'memcpy')相比,'std::string'的性能真的很差
- 错误/usr/include/string.h:652:42:错误:生成caffe时未在此作用域中声明“memcpy”
- 将内置数据类型转换为std::string: memcpy vs snprintf
- 使用memcpy()函数将字节从无符号char数组放入std::string