文档章节

c语言字符串转数字

guonaihong
 guonaihong
发布于 2015/08/30 22:01
字数 702
阅读 274
收藏 5

这是一个字符串转int的函数(libc 有同类函数strtol系列)

这虽然是个玩具函数,但在设计之初确定了如下目标:


1.函数原型模仿strtol,但是去掉strtol第二个参数

int str2int(char *str, int base); //玩具函数原型

long strtol(const char *restrict str, char **restrict endptr, int base);//libc库函数原型


2.扩展strtol函数(环境为mac libc)的进制猜测能力,当base为0时strtol函数会根据restric 的前缀为0x推测为16进制,0为8进制,玩具函数加入0b前缀表示2进制


3.支持2-36之间的进制。例如:z是10进制中的35

4.支持负数

5.测试4个字节所能表示的最大值,最小值,包含2,8,10,16进制


code

#include <stdio.h>
#include <ctype.h>

/*
 * @param base 可以是0或者2-36之间的任意整数
 * 如果是0,函数会自己猜测要转的进制,如果str是以0x开头,等同base为16
 * 如果str是0b开头,等同base为2
 * 如果str是0开头,等同base为8
 */ 
int str2int(char *str, int base) {
    char sign;
    int rv = 0;
    char c;
    int newbase = -1;

    if ((base < 2 && base != 0) || base > 36)
        return 0;

    //跳过str开头的空白字符
    while(*str && isspace(*str))
        str++;

    //取得符号位
    sign = (*str == '-' || *str == '+') ? *str++ : '+';

    //猜测需要转换的类型
    if (*str == '0' && ++str) {
        if ((*str == 'x' || *str == 'X') && ++str) {
            newbase = 16;
        } else if ((*str == 'b' || *str == 'B') && ++str) {
            newbase = 2;
        } else {
            newbase = 8;
        }
    }

    //默认10进制
    if (base == 0) {
        base = newbase == -1 ? 10 : newbase;
    }

    //printf("base = %d:%s\n", base, str);
    for (;*str; str++) {
        //大写转小写
        c = *str | 0x20;
        if (c >= 'a' && c <= 'z') {
            rv = rv * base + c - 'a' + 10;
        } else if (c >= '0' && c <= '9') {
            rv = rv * base + c - '0';
        } else {
            break;
        }
        //printf("rv = %d\n", rv);
    }
    
    return sign == '-' ? -rv : rv;
}

#include <stdlib.h>
#include <limits.h>
#include <assert.h>
int main() {

    //test
    //==== max=====
    //2进制
    assert(str2int("0b11111111111111111111111111111111", 0) == 0xFFFFFFFF);
    printf("2 max:%x\n", str2int("0b11111111111111111111111111111111", 0));
    printf("2 max:%x\n", str2int("0b11111111111111111111111111111111", 2));

    assert(str2int("0777777777777", 0) == 0xFFFFFFFF);
    //8进制
    printf("8 max:%x\n", str2int("0777777777777", 0));
    printf("8 max:%u\n", str2int("0777777777777", 0));
    printf("8 max:%x\n", str2int("0777777777777", 8));
    printf("8 max:%u\n", str2int("0777777777777", 8));

    assert(str2int("4294967295", 0) == 0xFFFFFFFF);
    //10进制
    printf("10 max:%u\n", str2int("4294967295	", 0));
    printf("10 max:%u\n", str2int("4294967295	", 10));

    assert(str2int("0xffffffff", 0) == 0xFFFFFFFF);
    //16进制
    printf("16 max:%x\n", str2int("0xffffffff", 0));
    printf("16 max:%x\n", str2int("0XFFFFFFFf", 0));
    printf("16 max:%x\n", str2int("0xffffffff", 16));
    printf("16 max:%x\n", str2int("0XFFFFFFFf", 16));

    assert(str2int("0b10000000000000000000000000000000", 0) == 0x80000000);
    //=====min=====
    //2进制
    printf("2 min:%x\n", str2int("0b10000000000000000000000000000000", 0));
    printf("2 min:%x\n", str2int("0b10000000000000000000000000000000", 2));
    printf("2 min:%d\n", str2int("0b10000000000000000000000000000000", 0));
    printf("2 min:%d\n", str2int("0b10000000000000000000000000000000", 2));

    assert(str2int("020000000000", 0) == 0x80000000);
    //8进制
    printf("8 min:%d\n", str2int("020000000000", 8));
    printf("8 min:%d\n", str2int("020000000000", 0));
    printf("8 min:%x\n", str2int("020000000000", 8));
    printf("8 min:%x\n", str2int("020000000000", 8));

    //10进制
    printf("10 min:%d\n", str2int("-2147483648", 10));
    printf("10 min:%x\n", str2int("-2147483648", 10));

    //16进制
    printf("16 min:%d\n", str2int("0x80000000", 16));
    printf("16 min:%x\n", str2int("0x80000000", 16));

    //printf("%x", strtoul("-2147483648", NULL, ));
    //35进制
    printf("35:%d\n", str2int("z", 35));
    return 0;
}



© 著作权归作者所有

guonaihong

guonaihong

粉丝 6
博文 83
码字总数 27591
作品 1
徐汇
程序员
私信 提问
c++-字符串和数字互相转换小结

在平常学习过程中,字符串转数字或者数字转字符串的题目都很多。所以现小结一下几种互相转换的方式: atoi(字符串转数字)/itoa(数字转字符串) 注:在使用itoa过程中报错:The POSIX nam...

sssssuuuuu666
2017/12/26
0
0
汇编总结:无符号除法,有符号除法,取余,无符号乘法,有符号乘法指令

本文分为3个模块。 示例---该指令的示例 解释---为指令不好理解的地方 练习---为了更熟悉该指令 1.1 有符号除法指令及取余example: 在c语言里要完成 8 / 2的汇编指令如下: 在c语言里要完成 ...

guonaihong
2015/10/07
2.2K
0
boost::lexical_cast

lexical_cast在boost库中的声明 lexicalcast定义在boost命名空间,使用时需要包含头文件<boost/lexicalcast.hpp>. lexical_cast由一组模版组成,不同的模版对应不同的数据类型转换。下面列出...

恋恋美食
2016/09/07
569
0
postgresql 字符串转数字,数字转字符串问题

使用postgreSql 赋值时,需要用到字符串转数字,不明白to_char(integer,char)两个参数的意思,谁能帮我解释下 select to_char(5,'999D9') as a ---得到5 select to_char(5,'7777') as a----......

聂超ps
2015/02/02
1W
2
JavaScript字符串转数字的5种方法及其陷阱

摘要 :JavaScript是一个神奇的语言,字符串转数字有5种方法,各有各的坑法! 原文: Converting Strings to Number in Javascript: Pitfalls 译者: Fundebug 为了保证可读性,本文采用意译而非...

Fundebug
2018/07/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Kettle自定义jar包供javascript使用

我们都知道 Kettle 是用 Java 语言开发,并且可以在 JavaScript 里面直接调用 java 类方法。所以有些时候,我们可以自定义一些方法,来供 JavaScript 使用。 本篇文章有参考自:https://www...

CREATE_17
昨天
82
0
处理CSV文件中的逗号

我正在寻找有关如何处理正在创建的csv文件的建议,然后由我们的客户上传,并且该值可能带有逗号(例如公司名称)。 我们正在研究的一些想法是:带引号的标识符(值“,”值“,”等)或使用|...

javail
昨天
79
0
如何克隆一个Date对象?

将Date变量分配给另一个变量会将引用复制到同一实例。 这意味着更改一个将更改另一个。 如何实际克隆或复制Date实例? #1楼 简化版: Date.prototype.clone = function () { return new ...

技术盛宴
昨天
73
0
计算一个数的数位之和

计算一个数的数位之和 例如:128 :1+2+8 = 11 public int numSum(int num) { int sum = 0; do { sum += num % 10; } while ((num = num / 10) > 0); return sum;......

SongAlone
昨天
124
0
为什么图片反复压缩后普遍会变绿,而不是其他颜色?

作者:Lion Yang 链接:https://www.zhihu.com/question/29355920/answer/119088684 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 业余版概要:安卓的...

shzwork
昨天
71
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部