函数实现-aoti-atol

1. 函数原型

    int atoi ( const char * str );
    long int atol ( const char * str );

2. 函数工作

    atoi是将字符串转化为整型,atol是将字符串转化为长整型,这两个函数的实现十分相似。工作步骤基本如下:
   ·跳过若干空格、制表符等
   ·如果有正号或者负号,进行识别
   ·将数字整合到结果中,直到字符串遍历完毕或者遇到数字以外的其他字符为止。
    C库中的atoi会尽可能的把更多的数字整合到结果中,不能发现数值溢出的问题。而且对于“整数+其他字符”这样的字符串识别出其中的“整数”,并不考虑后面的字符串中有没有非法字符。比如"1234abc",atoi的结果是1234,而不会认为"1234abc"本身是非法的。
    本文给出的aoti实现会考虑到如下几个方面:
    如果没有一个数字被整合到字符串中,抛出异常“没有数字存在”。
    如果数值溢出,抛出异常,“数值溢出”。
    对于"1234abc"这样的数字,保留原有atoi的处理形式,也识别出1234。

3. 函数设计

    为了更好的展示思路,这里我给出一个基于状态机的aoti实现。   

#include<iostream>
using namespace std;

int my_atoi(const char *str) {
  
if(str == NULL)
    
throw "str == NULL!";
  
enum STATE {STATE_SKIP_SPACE, STATE_RECOGNIZE_SIGN, STATE_RECOGNIZE_NUM,
    STATE_RECOGNIZE_LAST_NUM, STATE_RECOGNIZE_TAIL_CHAR};
  STATE state 
= STATE_SKIP_SPACE;
  
int max = INT_MAX;
  
int min = INT_MIN;
  
int bound = max / 10;
  
int sign = 1;
  unsigned 
int result = 0;
  
bool find_num = false;
  
while(true) {
    
switch(state) {
      
case STATE_SKIP_SPACE: // 跳过尽可能多的空格
        
if(*str==' '||*str=='\t'||*str=='\n'||*str=='\f'||*str=='\b'||*str=='\r')
          str
++;
        
else 
          state 
= STATE_RECOGNIZE_SIGN;
        
break;
      
case STATE_RECOGNIZE_SIGN: // 识别可能的正负符号
        
if(*str == '-') {
          str
++;
          sign 
= -1;          
        }
        
else if(*str == '+') {
          str
++;
        }
        state 
= STATE_RECOGNIZE_NUM;
        
break;
      
case STATE_RECOGNIZE_NUM: // 最多识别max/10的位数的数字 
        
if(*str <'0' || *str>'9' || *str=='\0'// 当前字符不是数字,或者已经结束 
          if(find_num == false// 一个数字都还没遇到过 
            throw  "no num found!";
          
else  // 已经遇到过数字了 
            return result * sign;
        
else { // 当前字符是数字 
          if(find_num == false)
            find_num 
= true;  
          result 
*= 10;
          result 
+= (*str-'0');
          bound 
/= 10;
          
if(bound ==0) {
            state 
= STATE_RECOGNIZE_LAST_NUM;
          }
          str
++;
        }
        
break;
      
case STATE_RECOGNIZE_LAST_NUM: // 识别最后一个数字
        
if(*str <'0' || *str>'9' || *str=='\0'// 当前字符不是数字,或者已经结束 
          return result * sign; // 能到这一步,肯定是已经遇到了很多数字 
        else { // 当前字符是数字
          if((result > max/10|| (sign==1 && (*str-'0')>(max%10)) || (sign==-1 && (*str-'0')>abs(min%10))) {
            
throw "over num limit !";
          }
          
else {
            result 
*= 10;
            result 
+= (*str - '0');
            state 
= STATE_RECOGNIZE_TAIL_CHAR;
            str
++;
          }
        }
        
break;
      
case STATE_RECOGNIZE_TAIL_CHAR: // 不能再识别数字了
        
if(*str <'0' || *str>'9' || *str=='\0'// 当前字符不是数字,或者已经结束
          return result * sign;
        
else // 当前字符是数字,此时必然溢出 
          throw "over num limit !";
        
break;
      
default:
        
break;
    }
  }
  
return 0;
}

int main() {
  
char* a = "        +123213123abc";
  
char* max = "     2147483647abc";
  
char* min = "     -2147483648abc";
  
char* max_more_1 = "     2999999997abc";
  
char* max_more_2 = "     2147483648abc";
  
char* min_more_1 = "     -2147483649abc";
  cout 
<< a << ":  " << my_atoi(a) << endl;
  cout 
<< max << ":  " << my_atoi(max) << endl;
  cout 
<< min << ":  " << my_atoi(min) << endl; 
  
try {
    cout 
<< max_more_1 << ":  ";
    my_atoi(max_more_1);
  }
  
catch (const char* info){
    cout 
<< info << endl;
  }
  
try {
    cout 
<< max_more_2 << ":  ";
    my_atoi(max_more_2);
  }
  
catch (const char* info){
    cout 
<< info << endl;
  }
  
try {
    cout 
<< min_more_1 << ":  ";
    my_atoi(min_more_1);
  }
  
catch (const char* info){
    cout 
<< info << endl;
  }
  
char wait;
  cin 
>> wait;
  
return 0;
}

    long int 的转化与int的转化差不多。

4. 参考资料
    C++ Reference atoi    http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/ 
    C/C++常见面试题(30)----atoi函数    http://blog.csdn.net/lzueclipse/archive/2011/05/26/6446945.aspx
    程序员面试题精选---“itoa函数”和“atoi函数    http://blog.csdn.net/zhangxinrun/archive/2010/12/01/6048695.aspx
    atoi的实现,一道对数值边界考察的题目    http://hi.baidu.com/xuelianglv/blog/item/cda76b2c52fbdded8a1399fe.html
    C库函数atoi的实现和一些讨论_c/c++_电脑编程网    http://blog.csdn.net/udknight/archive/2007/10/22/1836799.aspx   

转载于:https://www.cnblogs.com/pangxiaodong/archive/2011/06/17/2083471.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python2卸载后yum不可用_centos7误删除python2导致的python和yum不可用处理-阿里云开发者社区...

centos7查看版本cat /etc/redhat-release // 我这边是 CentOS Linux release 7.6.1810 (Core)强制删除已安装程序及其关联rpm -qa|grep python|xargs rpm -ev --allmatches --nodeps删除所有残余文件 ##xargs,允许你对输出执行其他某些命令whereis python |xargs rm -frv验证删…

arcgis批量按掩膜提取栅格

新建工具箱 迭代要素类 插入栅格

SIP协议学习1

SIP协议是由IETF提出的在IP网络上进行多媒体通信的应用层控制协议。采用分层的方法来创建服务&#xff0c;是应用层上的一个控制协议&#xff0c;用来创建&#xff0c;修改和终止有多个参与者的多媒体会话进程。参与会话的成员可以通过组播&#xff0c;单播或者两者结合的方式进…

一些关于罗马字符的知识

I 1 V 5 X 10 L 50 C 100 D 500 M 1000 下面是关于构造罗马数字的一些通用的规则的介绍&#xff1a; 字符是叠加的。I 表示 1&#xff0c;II 表示 2&#xff0c;而 III 表示 3。VI 表示 6 (字面上为逐字符相加&#xff0c;“5 加 1”)&#xff0c;VII 表示 7&#xff0c…

python 分词 识别_python分词如何实现新词识别

2013-12-19 回答# -*- coding: utf-8 -*-import jiebacreated on 2015-11-23def word_split(text):"""split a text in words. returns a list of tuple that contains(word, location) location is the starting byte position of the word."""…

Oracle数据库游标操作

1、含有参数的游标 declare cursor cur_my (mv number) is select * from Person where no<mv;begin for tem in cur_my(4) loop DBMS_OUTPUT.put_line(name:||tem.name); end loop;end; 2、设置引用游标declare temp_row Person%rowtype; type my_type is ref curs…

SIP协议学习2-pjsip

一、 在windows下利用vc6.0编译pjsip源码 首先阅读文档readme.txt&#xff0c;查找在win32平台源码的编译方法。自己总结方法如下&#xff1a; a.设置pjsua为当前活动工程 b.因为编译的时候提醒缺少config_site.h文件&#xff0c;所以在pjlib/include/pj/下新建一个空的c…

python库快速安装_python的pip快速安装代码

pip install xx,经常由于网速&#xff0c;或者安装版本问题导致安装速度慢超时等问题&#xff0c;现提供一个py镜像安装代码&#xff0c;安装库文件前执行下这个程序&#xff0c;可以很快下载cmd 进入命令提示符python .py文件位置pip install xx 安装库的名称import osini&quo…

基于C#的AE+IDL二次桌面端程序开发

目录 一、内容 1.2 实训内容 1.2.1 IDL综合开发 1.2.2 基于AO/AE的GIS二次开发 1.2.3 COM_IDL_connect组件开发 三、 实训软硬件环境 四、实训内容及成果 4.1 平台总体描述 4.1.1 系统简介 4.1.2 系统功能 4.2 基础模块 4.2.1…

PJSIP学习笔记——从simple_pjsua.c示例程序了解PJSUA-LIB的基本使用流程

要了解pjsip的使用&#xff0c;simple_pjsua.c是一个很好的例子&#xff0c;虽然代码只有短短的172行&#xff0c;却展示了pjsua-lib层的完整使用流程、注册流程和基本呼叫流程。 下面是学习过程中整理的simple_pjsua.c中的main函数主要流程&#xff1a; 先来看看pjsip-apps/s…

arcgis字段计算器--随机数

代码 def a():number arcgis.rand(Integer 0 25)return number 结果

tomcat webapps目录文件都能删吗_详细测试实现Tomcat根域名访问的场景,看这篇文章就够了...

写在前面的话首先吐槽一下&#xff0c;我发现国内的博客大多是垃圾&#xff0c;完全没有人测试代码&#xff0c;就在那瞎扯淡&#xff0c;如果你看到别的地方说的跟我的文章说的不一样&#xff0c;请以我这篇为准&#xff0c;因为我每个场景都经过N次测试&#xff0c;确保没有问…

C语言STATIC用法

C语言STATIC用法转自:http://blog.csdn.net/vagrantisme/article/details/4083722   1. static 变量  静态变量的类型 说明符是static。 静态变量当然是属于静态存储方式&#xff0c;但是属于静态存储方式的量不一定就是静态变量。 例如外部变量虽属于静态 存储方式&#x…

SIP初步

1、什么是SIP SIP&#xff08;会话发起协议&#xff09;属于IP应用层协议&#xff0c;用于在IP网上为用户提供会话应用。会话&#xff08;Session&#xff09;指两方或多方用户之间的语音、视频、及其他媒体形式的通信&#xff0c;具体可能是IP电话、会议、即时消息等等。 SIP…

execl按数值分类

LOOKUP(A1,{0,60,75,85},{"不合格","合格","良好","优秀"}) 参考文献 如何把excel中的数字转成优良中差等级_百度知道

synchronized原理_synchronized 底层原理与内存屏障

点击?蓝色“ 深入原理”&#xff0c;关注并“设为星标”技术干货&#xff0c;第一时间推送锁概述我们知道线程安全问题的产生前提是多个线程并发访问共享变量、共享资源(以下统称为共享数据)。于是&#xff0c;我们很容易想到保障线程安全的方法将多个线程对共享数据的并发访问…

boost helloworlld

原文地址&#xff1a; 使用环境ubuntu g安装boost只需要运行apt-get install libboost-dev libboost-dbg libboost-doc bcp libboost-*运行完毕就安装完了第一个例子,是使用boost中的lexical_cast组件的 #include <boost/lexical_cast.hpp>#include <iostream>int …

python处理ncdc气象数据并利用arcgis可视化

作者已经处理好的数据如下 中国2020年均气温数据点加栅格.zip-讲义文档类资源-CSDN下载 数据格式如下 所有文件 对2020年文件进行查看(共有412个站点数据) 打开其中一个进行查看共有12列数据

动态分区分配的“首次适应算法_动态图划分复制算法:Leopard

数据管理和系统实现课程上要分享的论文&#xff1a;《LEOPARD: Lightweight Edge-Oriented Partitioning and Replication for Dynamic Graphs》背景目前分析处理图数据已经成为一项重要的任务&#xff0c;例如&#xff0c;研究互联网结构&#xff0c;分析社会关系&#xff0c;…