如何将std::string转换为double

60
通常当我在C++中编写任何内容,并且需要将一个char转换为int时,我只需创建一个新的int,将其赋值为char。
我使用了以下代码片段:
 string word;  
 openfile >> word;
 double lol=word;

我收到了一个错误信息。
Code1.cpp cannot convert `std::string' to `double' in initialization 

这个错误具体是什么意思?第一个词是数字50。谢谢 :)

可能是科学计数法字符串C++转double的重复问题 - David Rodríguez - dribeas
这基本上是一个副本,唯一的区别是您甚至不需要经过字符串阶段,因为您可以直接读取到double。 - David Rodríguez - dribeas
3
将一个 char 转换成 int 时,得到的是字符对应的编码,而不是其看起来的“值”。换句话说,如果你在一个 ASCII 兼容环境中,语句 int x = '0'; 会将 x 赋值为 48,而不是 0 - Mike DeSimone
可能是重复的问题:如何在C++中将double转换为字符串? - jb.
1
不是重复的内容。@jb,再次强调,String->Double 不等于 Double->String - JasonMArcher
7个回答

85
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << stod("  99.999  ") << endl;
}

输出: 99.999 (这是double类型,空白自动被去除)

自从C++11起,将字符串转换为浮点数(如double)可使用以下函数:
stof - 将str转换为float类型
stod - 将str转换为double类型
stold - 将str转换为long double类型

由于问题中还提到了将字符串转换为整数,因此在C++11中有以下函数:
stoi - 将str转换为int类型
stol - 将str转换为long类型
stoul - 将str转换为unsigned long类型
stoll - 将str转换为long long类型
stoull - 将str转换为unsigned long long类型


82

你可以轻松地将char类型转换为int类型,反之亦然,因为对于计算机而言,int和char是相同的,都是8位,唯一的区别在于它们在屏幕上显示时的表现方式。例如,如果数字为65并保存为char,则会显示为'A',如果保存为int,则显示为65。

对于其他类型,情况会有所不同,因为它们在内存中的存储方式不同。在C语言中,有一个标准函数允许您轻松地将字符串转换为double类型,它就是atof函数。(需要包含stdlib.h头文件)

#include <stdlib.h>

int main()
{
    string word;  
    openfile >> word;
    double lol = atof(word.c_str()); /*c_str is needed to convert string to const char*
                                     previously (the function requires it)*/
    return 0;
}

17
问题在于C++是一种静态类型语言,这意味着如果某个变量被声明为string,它就是一个字符串,如果被声明为double,那么它就是一个双精度浮点数。与其他像JavaScript或PHP这样的语言不同,在C++中没有办法自动将字符串转换为数字值,因为这种转换可能是未定义的。例如,如果您尝试将字符串"Hi there!"转换为double,因为没有有意义的转换,你只能将double设置为0.0或NaN,但这几乎肯定掩盖了代码中存在的问题。
要解决这个问题,请不要将文件内容缓冲到字符串中。而是直接读取到 double 中:
double lol;
openfile >> lol;

该操作直接将值读取为实数,如果发生错误,流的 .fail() 方法会返回 true。例如:

double lol;
openfile >> lol;

if (openfile.fail()) {
    cout << "Couldn't read a double from the file." << endl;
}

2
如果您不是从流中读取数据,则需要使用函数来执行转换,例如来自<stdlib.h>atof()函数。 - Mike DeSimone
5
作为一个初学者,如果你没有从流中读取数据而是有一个字符串,你需要把它放到一个字符串流中并从那里读取。 - sbi

5

如果你正在从文件中读取数据,那么你应该听取建议,将其放入 double 中。

另一方面,如果你有一个字符串,你可以使用 boost 的 lexical_cast

这里是一个(非常简单的)例子:

int Foo(std::string anInt)
{
   return lexical_cast<int>(anInt);
}

1
下面的程序展示了解决转换问题的C++方式(而不是经典的C方式)。请注意,意图是能够使用iostream提供的相同格式化工具,如精度、填充字符、填充、十六进制和操纵器等等。请编译并运行此程序,然后学习它。这很简单。
#include "iostream"
#include "iomanip"
#include "sstream"
using namespace std;

int main()
{
    // Converting the content of a char array or a string to a double variable
    double d;
    string S;
    S = "4.5";
    istringstream(S) >> d;    
    cout << "\nThe value of the double variable d is " << d << endl;
    istringstream("9.87654") >> d;  
    cout << "\nNow the value of the double variable d is " << d << endl;



    // Converting a double to string with formatting restrictions
    double D=3.771234567;

    ostringstream Q;
    Q.fill('#');
    Q << "<<<" << setprecision(6) << setw(20) << D << ">>>";
    S = Q.str(); // formatted converted double is now in string 

    cout << "\nThe value of the string variable S is " << S << endl;
    return 0;
}

马丁内斯教授


请使用 <> 引用系统/编译器头文件,因为它们就是这样的文件。否则,编译器将首先查找本地编译目录,然后再查找由 -I 标志设置的包含目录。 - ranu

0
将字符串转换为双精度浮点数可以通过使用库 'stdlib.h' 中的 'strtod()' 函数实现。
#include <iostream>
#include <stdlib.h>
int main () 
{
    std::string data="20.9";
    double value = strtod(data.c_str(), NULL);
    std::cout<<value<<'\n';
    return 0;
}

1
在C++中,有一个名为nullptr的类型化空值,它是随着C++11标准一起推出的。 - ranu

-4
#include <string>
#include <cmath>
double _string_to_double(std::string s,unsigned short radix){
double n = 0;
for (unsigned short x = s.size(), y = 0;x>0;)
if(!(s[--x] ^ '.')) // if is equal
n/=pow(10,s.size()-1-x), y+= s.size()-x;
else
    n+=( (s[x]-48) * pow(10,s.size()-1-x - y) );
return n;
}

或者

//In case you want to convert from different bases.
#include <string>
#include <iostream>
#include <cmath>
double _string_to_double(std::string s,unsigned short radix){
double n = 0;
for (unsigned short x = s.size(), y = 0;x>0;)
if(!(s[--x] ^ '.'))
n/=pow(radix,s.size()-1-x), y+= s.size()-x;
else
    n+=( (s[x]- (s[x]<='9' ? '0':'0'+7)   ) * pow(radix,s.size()-1-x - y) );
return n;
}
int main(){
std::cout<<_string_to_double("10.A",16)<<std::endl;//Prints 16.625
std::cout<<_string_to_double("1001.1",2)<<std::endl;//Prints 9.5
std::cout<<_string_to_double("123.4",10)<<std::endl;//Prints 123.4
return 0;
}

2
这个无法编译,而且很难阅读,也没有使用标准库中已有的特性。此外,这个问题已经两年过去了并且已经有人回答了。 - unkulunkulu
1
这个代码确实可以编译。顺便说一下,我想提供一个算法,而非其他回答。 - ausercomment
1
你无法编译它的原因是_string_to_double中的arg1没有指定为命名空间std。现在已经修复。 - ausercomment
1
其他问题仍然存在:没有缩进,流程不清晰,间距完全不一致,名称以下划线开头。我对这个算法没有信心。而且这不是一个算法问题。 - unkulunkulu
3
这不是关于人生观的讨论。实际上,这根本不是一次讨论,一个更有经验的用户正在告诉您在这里哪些答案更受欢迎,就是这样。很少有人会尝试挖掘代码,即使它的作者没有努力使其易读。 - unkulunkulu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接