int
转换为等效的string
?我知道两种方法。还有其他方法吗?(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
int
转换为等效的string
?我知道两种方法。还有其他方法吗?int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
C++11 引入了std::stoi
(以及每种数字类型的变体)和std::to_string
,它们是 C 语言中 atoi
和 itoa
的对应物,但是使用了 std::string
。
#include <string>
std::string s = std::to_string(42);
所以这是我能想到的最短的方法。您甚至可以省略类型名称,使用auto
关键字:auto s = std::to_string(42);
注意:请参见 [string.conversions](21.5 在 n3242 中)
to_string
不是std
的成员。解决方法:https://dev59.com/smcs5IYBdhLWcg3wSSDH - Beng++ -std=c++11 someFile.cc
。 - Thomas M. DuBuissonstd
的一个成员。 - Mooing Duck错误:没有匹配参数列表的重载函数“std :: to_string”实例
。我正在使用VS2010 c ++。 - user2643530string s = to_string((_ULonglong)i);
。 - ZacC++20: 现在的惯用方式是使用std::format。
C++17:
几年后与 @v.oddou 讨论后,C++17 提供了一种无需使用宏丑陋代码的途径来实现最初基于宏的类型不可知解决方案(下面保留)。
// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
std::ostringstream sstr;
// fold expression
( sstr << std::dec << ... << args );
return sstr.str();
}
用法:
int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );
Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );
C++98:
由于“将...转换为字符串”是一个经常出现的问题,我总是在我的C++源代码的中央头文件中定义SSTR()宏:
#include <sstream>
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
使用非常简单:
int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );
Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );
如果你不能使用 C++11 的 std::to_string
和 Boost 的 lexical_cast<>
,上面的代码是兼容 C++98 的,并且不需要任何第三方库,但这两个其他解决方案的性能要更好。
dynamic_cast
不是很熟悉,但我正在使用clang进行编译,所以它抱怨了它。如果我只省略dynamic_cast
,那么它就可以正常编译;在这种情况下,dynamic_cast
起到什么作用?我们已经创建了一个ostringstream
,那么为什么还要进行转换? - Mathewostringstream
,但我们在其上调用了operator<<()
,它返回ostream&
--对于该类型,.str()
未定义。我真的很想知道clang如何在没有强制转换的情况下使其工作(或者为什么它使用强制转换会生成错误)。这个结构在许多地方都有发布,并且我已经在许多不同的编译器上使用它十多年,包括MSVC,GCC和XLC,所以我对clang的反应感到非常惊讶。 - DevSolardo { } while( 0 )
不会添加任何内容。对于第二点和第三点,你可能有一些观点——这可以通过静态转换来完成,也许你们其中的一位模板专家可以想出一个更好的接口。但是正如我所说,这绝不是我的发明。看看周围,这个宏(宏!)相当普遍。这本身就是 POLA 的一个例子。我可能会稍微玩弄一下,使其更加“简洁”。 - DevSolarC++11 开始,有一个为整数类型重载的 std::to_string
函数,因此您可以使用以下代码:
int a = 20;
std::string s = std::to_string(a);
// or: auto s = std::to_string(a);
这个标准定义了这些操作等价于使用sprintf
进行转换(使用与所提供对象类型相匹配的转换说明符,例如%d
表示int
),将其转换为足够大的缓冲区,然后创建包含该缓冲区内容的std::string
。
对于旧版(C++11之前)编译器,可能最常见的简单方法就是将基本上你的第二选择封装成一个通常称为lexical_cast
的模板,例如在Boost中的那个,因此您的代码看起来像这样:
int a = 10;
string s = lexical_cast<string>(a);
其中一个好处是它还支持其他类型的强制转换(例如,相反方向同样有效)。
同时需要注意的是,虽然 Boost 的 lexical_cast
最初只是写入一个 stringstream
中,然后从流中提取回来,但现在已经添加了一些功能。首先,已经为许多常见类型添加了特化,因此对于许多常见类型来说,它比使用 stringstream
更快。其次,它现在会检查结果,因此(例如)如果将字符串转换为 int
,如果字符串包含无法转换为 int
的内容(例如 123abc
),它可能会抛出异常。
我通常使用以下方法:
#include <sstream>
template <typename T>
std::string NumberToString ( T Number )
{
std::ostringstream ss;
ss << Number;
return ss.str();
}
这里详细描述了相关信息。
clear()
操作。clear()
函数会重置错误/文件结束标志位,但由于还没有发生任何错误/文件结束的情况,因此没有必要进行该操作。 - Remy LebeauNumberToString(23213.123)
产生的结果是 23213.1
,而 std::to_string(23213.123)
产生的结果是 23213.123000
。这是怎么回事? - Killzone Kid.flags(...)
读取和清除格式标志,使用.str("")
清除现有字符串。 - xryl669您可以使用C++11中提供的std::to_string
,如Matthieu M.所建议的那样::
std::string s = std::to_string(42);
或者,如果性能很重要(例如,如果您执行大量转换),则可以使用{fmt}库中的fmt::format_int
将整数转换为std::string
:
std::string s = fmt::format_int(42).str();
或者一个 C 字符串:
fmt::format_int f(42);
const char* s = f.c_str();
后者不执行任何动态内存分配,并且在 Boost Karma 基准测试中比 libstdc++ 实现的 std::to_string
快70%以上。有关详细信息,请参见每秒将一亿个整数转换为字符串。
免责声明:我是 {fmt} 库的作者。
c_str()
返回一个在fmt::FormatInt
类内声明的缓冲区指针——因此返回的指针将在分号处无效——请参见https://dev59.com/FG855IYBdhLWcg3wp2R0。 - Sorenstd::string::c_str()
相同的行为(因此命名为这个)。如果你想在完整表达式之外使用它,请构造一个对象 FormatInt f(42);
然后你可以使用 f.c_str()
而不必担心它被销毁。 - vitaut如果您已经安装了Boost(应该安装):
#include <boost/lexical_cast.hpp>
int num = 4;
std::string str = boost::lexical_cast<std::string>(num);
使用stringstream会更容易:
#include <sstream>
int x = 42; // The integer
string str; // The string
ostringstream temp; // 'temp' as in temporary
temp << x;
str = temp.str(); // str is 'temp' as string
或者创建一个函数:
#include <sstream>
string IntToString(int a)
{
ostringstream temp;
temp << a;
return temp.str();
}
就我所知,在纯C++中没有这样的功能。但是可以对你提到的东西进行一点修改。
string s = string(itoa(a));
应该可以工作,而且代码很短。
itoa()
不是标准函数! - cartoonistsprintf()
函数非常适合进行格式转换。然后,您可以像在 1. 中那样将生成的 C 字符串赋值给 C++ 字符串。
snprintf
(注意 SNP 前缀)和 sprintf
(注意 SP 前缀)。你向前者传递大小,它会避免溢出,然而后者不知道缓冲区的大小,因此可能会溢出。 - Matthieu M.snprintf
变体,然后再调用 sprintf
变体。由于此时缓冲区大小已知,因此调用 sprintf
变得完全安全。 - user1095108使用stringstream进行数字转换是危险的!
请看std::ostream::operator<<,其中说明了operator<<
插入已格式化的输出。
根据当前的区域设置,大于三位数的整数可能会转换为四位数的字符串,并添加额外的千位分隔符。
例如,int = 1000
可能会被转换为一个字符串 1.001
。这可能导致比较操作完全无效。
因此,我强烈建议使用std::to_string
方法。它更容易使用,并且达到预期的效果。
C++17 提供了
std::to_chars
作为一种更高效、独立于区域设置的替代方法。
std::to_string
也使用当前语言环境(请参见http://en.cppreference.com/w/cpp/string/basic_string/to_string,“注”部分)。几乎所有标准工具(从字符串流到`sprintf`,但也包括`sscanf`等)都使用当前语言环境。直到最近,当它严重影响我时,我才意识到这一点。目前使用自己编写的东西,不难制作。 - Bert Bril
itoa()
需要三个参数。 - arkon