• c++中string和int相互转化


      今天逛csdn的时候看到一篇讲atoi的博客,进去看了看,然后就想根据自己以前java中的转化仿造一把。

      1.  int  转  string 

        其实原理很简单(也是照搬JDK上的,稍微改了点).  加入有个整形 m,现需要转成字符串。可能你会想到每次除10取模然后再将余数变成字符。额,是的。但是这里并不想每次都除以10,而是100.这样每次就取出了两位,然后根据事先准备好的对应表直接将十位和个位取出来

      2. string 转  int

        其实atoi的内部实现就一句话   return  (int)atol(...)。 就是先转成long然后再强转到int. 我想最主要的问题还是可能的溢出。假如一个很长的string转成int必然会溢出,如果转成long不溢出,再转成int必然会被截断,我现在想返回最大或最小的整形。

      废话不说,直接上代码

    #ifndef __STINRG_2_INT_H
    #define __STING_2_INT_H
    #include <string>
    using  std::string;
    class StrIntConveter
    {
    public:
    	static char DigitTens[];
    	static char DigitOnes[];
    	static int sizeTable[];
    	static int StringSize(int);
    	static string ToString(int);   //int 转string
    	static void GetChars(int i,int index ,char buf[]);  //内部实际使用
    	static bool ParseInt(const string&,int& );  //整形转string
    	static bool ParseInt(const string& ,int&,int);//内部实际使用
    protected:
    private:
    };
    #endif
    
    
    #include "string2int.h"
    #include "character.h"
    char StrIntConveter::DigitTens[]={'0', '0', '0', '0', '0', '0', '0', '0',
    '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2',
    '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3',
    '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4',
    '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
    '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7',
    '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8',
    '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9',
    '9', };
    char StrIntConveter::DigitOnes[]={'0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
    '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3',
    '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6',
    '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2',
    '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5',
    '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8',
    '9', };
    int StrIntConveter::sizeTable[]= { 9, 99, 999, 9999, 99999, 999999, 9999999,
    99999999, 999999999, INT_MAX };
    int StrIntConveter::StringSize(int x)
    {
    	for (int i=0;;i++)
    	{
    		if (x<=sizeTable[i])
    			return i+1;
    	}
    }
    string StrIntConveter::ToString(int i)
    {
    	if (i==INT_MIN)
    		return "-2147483648";
    	//获得要转换的整数一共有多少位,包含符号位
    	int size=(i<0)?StringSize(-i)+1:StringSize(i);
    	char* tmp=new char[size+1];
    	tmp[size]='\0';  //以为new char时会自动将数据清0.没想到啊。所以这里必须显示的设置一下
    	GetChars(i,size,tmp);
    	string retValue= string(tmp);
    	delete [] tmp;
    	return retValue;
    }
    void StrIntConveter::GetChars(int i,int index ,char buf[])
    {
    	int q,r;
    	int charPos=index;
    	char sign=0;  //符号位
    	if (i<0)
    	{
    		sign='-';
    		i=-i;
    	}
    	//为了提高效率,每次产生2位,然后尽量用位运算
    	while (i>100)
    	{
    		q=i/100;
    		r=i-((q<<6)+(q<<5)+(q<<2));//取2位的余数
    		i=q;
    		buf[--charPos]=DigitOnes[r];
    		buf[--charPos]=DigitTens[r];
    	}
    	//JDK处理小于65535的情况不好用c++处理,所以用了自己的办法
    	if(q==100){
    		buf[--charPos] = '0';
    		buf[--charPos] = '0';
    		buf[--charPos] = '1';
    	}else if(q<10){
    		buf[--charPos]=DigitOnes[i];
    	}else{
    		buf[--charPos]=DigitOnes[q];
    		buf[--charPos]=DigitTens[i];
    	}
    	if(sign!=0){
    		buf[--charPos]=sign;
    	}
    }
    bool StrIntConveter::ParseInt(const string&s , int & retValue)
    {
    	if (ParseInt(s,retValue,10))
    		return true;
    	return false;
    }
    bool StrIntConveter::ParseInt(const string &s, int &retValue, int radix)
    {
    	if (s.empty() || s=="")
    	{
    		retValue=0;
    		return true;
    	}
    	if (radix<Character::MIN_RADIX || radix>Character::MAX_RADIX)
    		return false;
    	bool negative=false;  //表示正负
    	int result=0;                //转换结果
    	int limit;                     //极限范围
    	int multmin;                //在 *radix之前的极限
    	int i=0,maxl=s.size();
    	int tmpDigit;            //每次取出的字符
    	if (maxl>0)
    	{
    		if (s.at(0)=='-')
    		{
    			negative=true;
    			limit=INT_MIN;
    			i++;
    		}else
    		{
    			limit=-INT_MAX;  //在这里也将正数先表示为负数,返回结果的时候再判断(所有都为了统一后面的操作)
    		}
    		multmin=limit/radix;
    		if (i<maxl)
    		{
    			tmpDigit=Character::Digit(s.at(i++),radix);
    			if (tmpDigit<0)
    			{
    				return false;
    			}else
    				result=-tmpDigit;
    		}
    
    		while (i<maxl)
    		{
    			tmpDigit=Character::Digit(s.at(i++),radix);
    			if (tmpDigit<0)
    			{
    				return false;
    			}
    			if (result<multmin)  //已经到极限了
    			{
    				//这里会出现溢出,但是为了程序健壮将直接返回最大值
    				result=limit;
    				break;
    			}
    			result*=radix;
    			if (result<limit+tmpDigit)
    			{
    				result=limit;
    				break;
    			}
    			result-=tmpDigit;
    		}
    	}
    	else 
    	{
    		retValue=0;
    		return true;
    	}
    	if (negative)
    	{
    		if (i>1)
    		{
    			retValue=result;
    			return true;
    		}else  //仅仅只有一个  ‘-’
    		{
    			return false;
    		}
    	}else
    	{
    		retValue=-result;
    		return true;
    	}
    
    }
    

      

    #ifndef __CHARACTER_H
    #define __CHARACTER_H
    class Character
    {
    public:
    	static int MIN_RADIX;   //最小进制
    	static int MAX_RADIX; //最大进制
    	static char MIN_CHAR;
    	static char MAX_CHAR;
    	static int Digit(char ch,int radix);
    protected:
    private:
    };
    #endif
    
    
    #include "character.h"
    #include <ctype.h>
    int Character::MIN_RADIX=2;
    int Character::MAX_RADIX=36;
    char Character::MIN_CHAR='\0';
    char Character::MAX_CHAR=0xff;
    //将一个radix进制的数转换成对应的十进制
    //其中负数表示失败
    int Character::Digit(char ch, int radix)
    {
    	if (radix<MIN_RADIX || radix>MAX_RADIX)
    	{
    		return -1;
    	}
    	if (radix<=10)
    	{
    		if (ch>='0' && ch<='9')
    		{
    			return ch-'0';
    		}
    		return -1;
    	}
    	int upperChar=toupper(ch);
    	int limit='A'+radix-11;
    	if (upperChar>limit)
    		return -1;
    	return 10+upperChar-'A';
    }
    

      这是些测试用的

    #include <iostream>
    #include <string>
    #include "string2int.h"
    using std::cout;
    using std::cin;
    using std::string;
    int main()
    {
    	/*int i=0;
    	cout<<"请输入要转成string的 整数\n";
    	cin>>i;
    	while (i!=1)
    	{
    		cout<<StrIntConveter::ToString(i)<<"\n";
    		cin>>i;
    	}*/
    	int result=0;
    	string tmp;
    	cout<<"请输入要转成int 的string\n";
    	cin>>tmp;
    	while (tmp!="quit")
    	{
    		if (StrIntConveter::ParseInt(tmp,result))
    		{
    			cout<<"转换的结果是"<<result<<"\n";
    			cin>>tmp;
    		}else{
    			cout<<"转换失败\n";
    			break;
    		}
    		
    	}
    	system("pause");
    	return 0;
    }
    

      

  • 相关阅读:
    P2018 消息传递[dp]
    P1436 棋盘分割[dp]
    一条线段引发的思考
    浅谈树上差分
    P2680 运输计划[二分+LCA+树上差分]
    P1600 天天爱跑步[桶+LCA+树上差分]
    P4560 [IOI2014]Wall 砖墙
    P1311 选择客栈[模拟]
    P1314 聪明的质监员[二分答案]
    Linux snmp导入MIB库
  • 原文地址:https://www.cnblogs.com/sandynie/p/3118727.html
Copyright © 2020-2023  润新知