字符串浮动转换?

我想知道什么样的算法可以用来将类似“4.72”的东西变成浮点数据类型,等于

float x = 4.72; 

scanfoperator>> for istreams, strtof将是明显的选择。

还有atof ,但是,像atoi一样,它没有办法告诉你输入中有错误,所以通常最好避免两者。

对于C ++,您可以使用boost :: lexical_cast :

  std::string str( "4.72" ); float x = boost::lexical_cast< float >( str ); 

对于C,您可以使用sscanf:

  char str[]= "4.72"; float x; sscanf( str, "%f", &x ); 

对于C ++这是我使用的算法:

 bool FromString(const string& str, double& number) { std::istringstream i(str); if (!(i >> number)) { // Number conversion failed return false; } return true; } 

我过去使用atof()进行转换,但我发现这有问题,因为如果无法进行有效转换,它将返回(0.0)。 所以,你不知道它是否失败并返回零,或者字符串实际上是否为“0”。

对于C strtod()C99朋友, strtof()strtold() (在同一链接上的描述)已经实现了该算法。

如果您在编写自己的问题时遇到问题,请发布您的代码和有关它的具体问题。

正如您所要求的算法而不是方法,这是我对简单算法(以及C中的实现)的解释:

  1. 初始化4个整数变量,一个用于点之前的值,一个用于后部,一个用于尾数的幂,一个用于符号。 比方说,f,m,d,sign = 1。
  2. 首先在开头查找+或 – 符号。 如果没有符号字符或+号,则继续。 如果第一个字符是 – ,则sign = -1。
  3. 然后,将整数值读入f直到a。 或NULL字符。
  4. 如果你最后得到一个点字符,那么就像上一步一样将尾数部分读入m。 但是这次每个数字也乘以d乘以10。
  5. 最后,返回符号*(f +(float)m / d)。 转换确保除法在浮点中完成,表达式的类型为float。

我想,阅读代码可能会更容易。 所以这是代码:

 float atof(char *s) { int f, m, sign, d=1; f = m = 0; sign = (s[0] == '-') ? -1 : 1; if (s[0] == '-' || s[0] == '+') s++; for (; *s != '.' && *s; s++) { f = (*s-'0') + f*10; } if (*s == '.') for (++s; *s; s++) { m = (*s-'0') + m*10; d *= 10; } return sign*(f + (float)m/d); } 

我假设您需要一个实际的算法,而不是已经完成它的库函数。 我没有时间编写和测试实际代码,但这是我要做的:

  1. 初始化一个将用作累加器的浮点数为0。
  2. 弄清楚字符串中小数位的位置,这将让你知道每个数字的“列”(即100s,10s,1s,1 / 10th等)。
  3. 从字符串的开头开始。
  4. 取这个数字,转换为int(通过从ASCII值减去0x30来完成)
  5. 将值乘以位置列(对于示例中的第一个数字,即4 * 1 == 4,对于下一个数字7 * 0.1 == 0.7)。
  6. 将结果添加到累加器
  7. 对于每个剩余的数字,从步骤4开始重复
  8. 累加器现在包含您的结果。

由于在该循环的每次迭代中在基数10和基数2之间进行转换,因此从该算法得到的结果可能不是与原始值最接近的可能二进制表示。 我真的不知道改善它的好方法……也许别人可以用它来说明。

atof()函数可能会有所帮助。 http://www.cplusplus.com/reference/clibrary/cstdlib/atof/

来自cplusplus.com:“stringstream提供了一个操作字符串的接口,就好像它们是输入/输出流一样。”

您可以使用字符串初始化字符串流,然后使用operator>>从字符串流中读取浮点数,就像使用cin

这是一个例子:

 #include #include #include using namespace std; int main() { string s = "4.72"; stringstream sstrm(s); float x; sstrm >> x; cout << x << endl; }