C语言字串转换、字元测试

若要将字串转换为数字,则可以使用atofatoiatolatoll等函式,这些函式都包括在stdlib.h 中:

double    atof( const char* str );
int       atoi( const char *str );
long      atol( const char *str );
long long atoll( const char *str );

atofatoiatolatoll等函式会搜寻字串中可以转换的部份,直到遇到无法转换的字元,字串开头可以使用正负号,例如"+100""-100"atof可以接受科学记号,例如"12.3e-5""123E+4",这几个函式若没有可转换的字元则传回0,若是转换结果超出了传回型态的范围,传回值没有定义,也就是难以检查错误。

C99 有一系列转换字串的函式,使用起来比较麻烦一些:

long               strtol( const char *restrict str, char **restrict str_end, int base );
long long          strtoll( const char *restrict str, char **restrict str_end, int base );

unsigned long      strtoul( const char *restrict str, char **restrict str_end,int base );
unsigned long long strtoull( const char *restrict str, char **restrict str_end,
                             int base );
float              strtof( const char *restrict str, char **restrict str_end );
double             strtod( const char *restrict str, char **restrict str_end );
long double        strtold( const char *restrict str, char **restrict str_end );

这几个函式的第一个参数都接受来源字串;第二个参数在函式执行过后,会用来储存字串中第一个无法剖析为数字的字元位址,如果设定为NULL,会忽略这个参数;第三个参数用来指定基底,如果设定为0,从字串中自动侦测基底;函式若没有可转换的字串,会传回0。

因此最简单的转换情况就是当成atof的替代品:

#include <stdio.h>
#include <stdlib.h>

int 主函数(无效){
    printf("\"1010\"\t二进位:\t%ld\n", strtol("1010", NULL, 2));
    printf("\"12\"\t八进位:\t%ld\n", strtol("12", NULL, 8));
    printf("\"A\"\t十六进位:\t%ld\n", strtol("A", NULL, 16));
    printf("\"012\"\t自动读取:\t%ld\n", strtol("012", NULL, 0));
    printf("\"0xA\"\t自动定位:\t%ld\n", strtol("0xA", NULL, 0));
    printf("\"junk\"\t自动读取:\t%ld\n", strtol("junk", NULL, 0));

  返回0;
}

执行结果如下:

"1010"  二进位:        10
"12"    八进位:        10
"A"     十六进位:      10
"012"   自动基底:      10
"0xA"   自动基底:      10
"junk"  自动基底:      0

若是转换结果超出了传回型态的范围,会将定义在errno.h 的errno设为ERANGE,并传回各自传回型态的最大可容许数值(最大值或最小值),因此,可藉由检查errno来看看转换是否有误:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main(void) {
    long i = strtol("99999999999999999999999999999999999999999999999999", NULL, 10);

    if(errno == ERANGE) {
        printf("超出转换函式范围");
        errno = 0;
    }
    else {
        printf("%d", i);
    }

    return 0;
}

由于第二个参数在函式执行过后,会用来指向字串中第一个无法剖析为数字的字元,因此若想连续剖析一组数字,数字以某一标点符号区隔,可以如下,这需要认识更多指标的观念,你可以在后续学习过指标之后,再回头看看这个范例:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main(void) {
    const char *p = "10,200,3000,-400000";
    char *end;
    for (long i = strtol(p, &end, 10); p != end; i = strtol(p, &end, 10)) {
        printf("\"%.*s\":", (int)(end - p), p);
        p = end + 1;  // 新的字串起点
        if (errno == ERANGE){
            printf("转换超出范围");
            errno = 0;
        }

        printf("%ld\n", i);
    }
}

由于第二个参数在函式执行过后,会用来指向字串中第一个无法剖析为数字的字元,因此若想连续剖析一组数字,数字以某一标点符号区隔,可以如下,这需要认识更多指标的观念,你可以在后续学习过指标之后,再回头看看这个范例:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main(void) {
    const char *p = "10,200,3000,-400000";
    char *end;
    for (long i = strtol(p, &end, 10); p != end; i = strtol(p, &end, 10)) {
        printf("\"%.*s\":", (int)(end - p), p);
        p = end + 1;  // 新的字串起点
        if (errno == ERANGE){
            printf("转换超出范围");
            errno = 0;
        }

        printf("%ld\n", i);
    }
}

执行结果如下:

"10":10
"200":200
"3000":3000
"-400000":-400000

若要测试字元为数字、字母、大写、小写等等

isalnum(int c):是否为字母或数字
isalpha(int c):是否为字母
iscntrl(int c):是否为控制字元
isdigit(int c):是否为数字
islower(int c):是否为小写字母
isprint(int c):是否为列印字元
ispunct(int c):是否为标点符号
isspace(int c):是否为空白
isupper(int c):是否为大写字母
isxdigit(int c):是否为16进位数字
...

这些函式事实上是巨集,可以查看ctype.h 得知更多的isxxxx函式,ctype.h 中也包括了像是可以进行字母大小写转换的tolowertoupper等函式。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值