我需要处理的数据范围是0-1999.99,这个是在浮点的精度范围内的。
例如如,会遇到如下字符串:
0.00077777->0
0.200000->0.2
2.00000->2
2.55555->2.55
1000.66666->1000.66
1999.00000->1999
->后面是最后想要的字符。
我目前用的下面的办法,我担心这样转换最终会在Section2中出现科学计数法e。不知哪位大神帮我看看能不能行。或者有其他更好的方法
CString strTemp,Section2
FLOAT XX=atof(strTemp); //必须先转浮点数,用来计算。
strTemp.Format("%.2f",XX); //先转化成字符,截断,保留小数点后两位。
XX=atof(strTemp); //再转化成浮点,因为浮点,这里不会小数点后两位。
Section2.Format("X=%g",XX);//这里好像四舍五入,再去掉零,最后得到想要的结果,
// Q766008.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Q766008.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
CWinApp theApp;
using namespace std;
void conv1(double d, int* a, int *b)
{
// int id = (int)(d * 100 + 0.5);如果要四舍五入,用这个
int id = (int)(d * 100);
*a = id / 100;
*b = id % 100;
}
void conv(double d, char * buffer)
{
int x;
int y;
conv1(d, &x, &y);
if (x == 0 && y == 0)
{
sprintf(buffer, "0");
}
else if (y == 0)
{
sprintf(buffer, "%d", x);
}
else if (y < 10)
{
sprintf(buffer, "%d.0%d", x, y);
}
else
{
if (y % 10 != 0)
sprintf(buffer, "%d.%d", x, y);
else
sprintf(buffer, "%d.%d", x, y / 10);
}
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
//CString strHello;
//strHello.LoadString(IDS_HELLO);
//cout << (LPCTSTR)strHello << endl;
double arr[] = { 0.00077777, 0.200000, 2.00000, 2.55555, 1000.66666, 1999.00000 };
for (int i = 0; i < 6; i++)
{
char buffer[100];
conv(arr[i], buffer);
CString str = (CString)buffer;
cout << (LPCTSTR)str << endl;
}
}
return nRetCode;
}
0
0.2
2
2.55
1000.66
1999
Press any key to continue
本代码的限制:
转换的值必须是>=0
转换的值必须小于2100万。
可以保证在以上条件下满足你的需求
首先第一个你的做法是:
先将字符串转换成float,然后通过转换成字符串的方式获得保留2位小数后的字符串,最后将字符串再转化为float;
其实完全可以简化下:
先处理字符串,直接保留字符串小数量后的2位字符,然后再转换成float就行了
还有一个问题就是你怕Section2.Format("X=%g",XX)会以指数形式输出; 这个是不会的 因为你的范围是0-1999.99,具体参考https://blog.csdn.net/you_shou/article/details/51198615
我写了个测试代码了看下是否能用上吧,我用的是通过正则表达式去掉小数点后2位后的所有字符:
#include<iostream>
#include<regex>
int main(void){
std::string str = "1999.9957819";
std::regex pattern("(.*?\\.\\d{2})(.*?)$");
str = std::regex_replace(str, pattern,"$1");
std::cout << str << std::endl;
float ft = atof(str.c_str());
printf("%g",ft);
return 0;
}
运行结果:
#include "stdio.h"
#include "string.h"
//将字符串转换为定点数,int存储定点数,pos存储定点数的模
void str2Dec(char* str, int* val, int* pos)
{
*val = 0;
*pos = 0;
for (int i = 0; i < strlen(str); i++)
{
if (str[i] == '.')
{
*pos = 1;
}
else
{
*val *= 10;
*val += (str[i] - '0');
if (*pos != 0) *pos *= 10;
}
}
if (*pos == 0) *pos = 1;
}
//这里借鉴下前面专家的代码
void conv(int x, int y, char * buffer)
{
if (x == 0 && y == 0)
{
sprintf(buffer, "0");
}
else if (y == 0)
{
sprintf(buffer, "%d", x);
}
else if (y < 10)
{
sprintf(buffer, "%d.0%d", x, y);
}
else
{
if (y % 10 != 0)
sprintf(buffer, "%d.%d", x, y);
else
sprintf(buffer, "%d.%d0", x, y / 10);
}
}
int main(int argc, char* argv[])
{
char * s = "1.123111";
char x[100];
int v, p;
str2Dec(s, &v, &p);
conv(v / p, (v * 100 / p) % 100, x);
printf("%s\n", x);
return 0;
}
为什么说有一个人是回答错误
首先
regex不是所有编译器都支持
其次,regex在一些情况下造成内存泄漏,不能实现可靠的代码
最后,这个不用我说,lz自己测试下
#include <iostream>
#include <sstream>
#include <string>
#include<regex>
using namespace std;
template <class T>
std::string ConvertToString(T value) {
stringstream ss;
ss << value;
return ss.str();
}
int main(void){
for (int i = 0; i < 99999; i++)
{
std::string str = ConvertToString(i);
str = "0." + str;
std::regex pattern("(.*?\\.\\d{2})(.*?)$");
str = std::regex_replace(str, pattern,"$1");
std::cout << str << " ";
float ft = atof(str.c_str());
printf("%g\n",ft);
}
return 0;
}
转换10万次,不是很多次吧,要多少时间,慢不慢?