字符串转64位无符号数C语言实现

0 前言

本文介绍使用C库自带的函数实现字符串转64位无符号数的方法,简单好用!

1 函数实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
 * @brief 计算数x的y次幂
 * 
 * @param x 数x
 * @param y y次幂
 * @return 结果
 */
unsigned long long int pow_u64(unsigned long long int x, unsigned long long y)
{
    unsigned long long i;
    unsigned long long ret = 1;
    if (y == 0)
    {
        return 1;
    }
    for (i = 0; i < y; i++)
    {
        ret *= x;
    }
    return ret;
}

/**
 * @brief 字符串转64位无符号数
 * 
 * @param str 字符串
 * @param binary 进制选择:10/16
 * @return unsigned long long int 结果
 */
unsigned long long int str_to_u64_bin(char *str, int binary)
{
    char *ptr;
    unsigned long long int ret;
    unsigned long long int ret1;
    unsigned long long int ret2;
    unsigned long long int ret3;
    int p1, p2, p3;
    int len1, len2, len3;

    /* 用10进制表示s64最大的数长度为20 */
    char str1[15] = {0};
    char str2[15] = {0};
    char str3[15] = {0};
    int len = strlen(str);
    if (len > 20)
    {
        return 0;
    }
    
    len1 = (float)len / 3;
    len2 = (float)len / 3;
    len3 = len - len2 - len1;
    

    p1 = 0;
    p2 = len1;
    p3 = len1 + len2;

    /* 将字符串分3块处理 */
    strncpy(str1, &str[p1], len1);
    strncpy(str2, &str[p2], len2);
    strncpy(str3, &str[p3], len3);

    ret1 = strtoul(str1, &ptr, binary);
    ret2 = strtoul(str2, &ptr, binary);
    ret3 = strtoul(str3, &ptr, binary);
    
    ret = ret1 * pow_u64(binary, len2 + len3) 
        + ret2 * pow_u64(binary, len3)
        + ret3;

    return ret;
}

/**
 * @brief 字符串转64位无符号数
 * 
 * @param str 10/16进制字符串
 * @return unsigned long long int 结果
 */
unsigned long long int str_to_u64(char *str)
{
    if ((strstr(str, "0x") != NULL) || (strstr(str, "0X") != NULL))
    {
        /* 16进制转u64 */
        return str_to_u64_bin(str, 16);
    }
    /* 10进制转字符串 */
    return str_to_u64_bin(str, 10);
}

函数说明:
(1)对外的接口是str_to_u64函数,支持10/16进制字符串转64位无符号数。如果有需要可以通过修改str_to_u64_bin函数支持更多进制
(2)strncpy、strtoul是C库自带函数
(3)pow_u64是自己实现的一个计算数x的y次幂的函数
实现思路:
C库自带的字符串转数字函数最多支持32位,我们将传入的字符串拆解成3份,使用C库自带的字符串转数字函数将3份字符串对应的数字转换出来,然后按照每个字符串在源字符串中的位置,将实际的数字大小还原出来。

2 功能测试验证

2.1 10进制字符串转64位无符号数测试

构造从0到64位无符号数上限的字符串去测试字符串转64位无符号数函数显然是不现实的,64位无符号数能表示的最大大小是:18446744073709551615,对应字符串长度为20。我们构造长度为1-20的字符串,传入我们设计好的str_to_u64函数,查看是否都能正确转换。函数设计:

void check_u64_value(void)
{
    int i;
    unsigned long long int val;
    char str[25] = {0};
    for (i = 0; i <= 19; i++)
    {
        val = pow_u64(10, i);
        sprintf(str, "%llu", val);
        if (str_to_u64(str) == val)
        {
            printf("[ OK ] Val : %llu\r\n", val);
            printf("       Ret : %llu\r\n", str_to_u64(str));
        }
        else
        {
            printf("[FAIL] Val : %llu\r\n", val);
            printf("       Ret : %llu\r\n", str_to_u64(str));
        }
    }
}

执行结果:

[ OK ] Val : 1
       Ret : 1
[ OK ] Val : 10
       Ret : 10
[ OK ] Val : 100
       Ret : 100
[ OK ] Val : 1000
       Ret : 1000  
[ OK ] Val : 10000 
       Ret : 10000 
[ OK ] Val : 100000
       Ret : 100000
[ OK ] Val : 1000000
       Ret : 1000000
[ OK ] Val : 10000000
       Ret : 10000000
[ OK ] Val : 100000000
       Ret : 100000000
[ OK ] Val : 1000000000
       Ret : 1000000000
[ OK ] Val : 10000000000
       Ret : 10000000000
[ OK ] Val : 100000000000
       Ret : 100000000000
[ OK ] Val : 1000000000000
       Ret : 1000000000000
[ OK ] Val : 10000000000000
       Ret : 10000000000000
[ OK ] Val : 100000000000000
       Ret : 100000000000000
[ OK ] Val : 1000000000000000
       Ret : 1000000000000000
[ OK ] Val : 10000000000000000
       Ret : 10000000000000000
[ OK ] Val : 100000000000000000
       Ret : 100000000000000000
[ OK ] Val : 1000000000000000000
       Ret : 1000000000000000000
[ OK ] Val : 10000000000000000000
       Ret : 10000000000000000000

可以看到1-20长度的字符串都被正确转换。

2.2 16进制字符串转64位无符号数测试

构造从0到64位无符号数上限的字符串去测试字符串转64位无符号数函数显然是不现实的,使用16进制表示64位无符号数最大值对应字符串是:0xffffffffffffffffffffffffffffffff,对应字符串长度为18。我们构造长度为3-18的字符串,传入我们设计好的str_to_u64函数,查看是否都能正确转换。函数设计:

void check_u64_value(void)
{
    int i;
    unsigned long long int val;
    char str[25] = {0};
    val = 0;
    for (i = 0; i < 16; i++)
    {
        val = (val << 4) | 0xf;
        sprintf(str, "0x%llx", val);
        if (str_to_u64(str) == val)
        {
            printf("[ OK ] Val : 0x%llx\r\n", val);
            printf("       Ret : 0x%llx\r\n", str_to_u64(str));
        }
        else
        {
            printf("[FAIL] Val : 0x%llx\r\n", val);
            printf("       Ret : 0x%llx\r\n", str_to_u64(str));
        }
    }
}

执行结果:

[ OK ] Val : 0xf
       Ret : 0xf
[ OK ] Val : 0xff
       Ret : 0xff
[ OK ] Val : 0xfff
       Ret : 0xfff
[ OK ] Val : 0xffff
       Ret : 0xffff
[ OK ] Val : 0xfffff
       Ret : 0xfffff
[ OK ] Val : 0xffffff
       Ret : 0xffffff
[ OK ] Val : 0xfffffff
       Ret : 0xfffffff
[ OK ] Val : 0xffffffff
       Ret : 0xffffffff
[ OK ] Val : 0xfffffffff
       Ret : 0xfffffffff
[ OK ] Val : 0xffffffffff
       Ret : 0xffffffffff
[ OK ] Val : 0xfffffffffff
       Ret : 0xfffffffffff
[ OK ] Val : 0xffffffffffff
       Ret : 0xffffffffffff
[ OK ] Val : 0xfffffffffffff
       Ret : 0xfffffffffffff
[ OK ] Val : 0xffffffffffffff
       Ret : 0xffffffffffffff
[ OK ] Val : 0xfffffffffffffff
       Ret : 0xfffffffffffffff
[ OK ] Val : 0xffffffffffffffff
       Ret : 0xffffffffffffffff

可以看到3-18长度的字符串都被正确转换。

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NW嵌入式开发

感谢您的支持,让我们一起进步!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值