C语言中的 String API

概述

String类型

c语言中String类型的具体定义为char* .因此可以声明String类型为:

typedef char* String;

字符串常量与字符数组

字符串常量

 以"abcdef"形式出现的为字符串常量,字符串常量的字面类型为char*。字符串常量存储在内存中的常量存储区中。字符串常量的标志是结尾存在不可见字符'\0'(ASCII值为0).

/* 字符串常量,char指针直接指向常量区中的地址 */
char *str1 = "abcde";  // 字符串常量的字面类型为 char*
/* 字符数组 */
char str2[] = {'a','b','c','d','e'};
/* 字符数组 */
char str3[] = "abcde";
printf("%d ",sizeof(str1));  // print "8 "
printf("%d ",sizeof(str2));  // print "5 "
printf("%d\r\n",sizeof(str3));  // print "6"
for(int len=0;len<sizeof(str3);len++) {
    printf("%d ",*(str3+len));  // print "97 98 99 100 101 0 "
}

 由于"abcdef"的字面类型为char*,以下操作也是正确的:

char ch1 = "abcde"[2];
char ch2 = *("abcde"+2);
printf("%c ",ch1);  // print "c "
printf("%c ",ch2);  // print "c "

字符数组

 字符数组即char型数组。字符数组的赋值方式有:

char str1[] = {'a','b','c','d','e'};  // 无 '\0'
/* 字符数组从常量字符串中依次读取字符,再复制到数组单元中。
   字符数组指针指向变量区的地址,而并非直接指向常量 */
char str2[] = "abcde";  // 有 '\0'
printf("%d ",sizeof(str1));  // print "5 "
printf("%d ",sizeof(str2));  // print "6 "
for(int len=0;len<sizeof(str2);len++) {
    printf("%d ",*(str2+len));  // print "97 98 99 100 101 0 "
}

字符串的只读性

 为方便表述,将字符串变量(char*)称为字符串引用,将字符串常量"abcde"称为字符串值。不可通过字符串引用更改字符串值中的某个字符,因为字符串引用直接引用对应的字符串常量(char指针直接指向常量区中的地址),而常量是只读的。

/* 字符串引用不可改变字符串值,但可引用其它字符串 */
#ifndef String
typedef char* String;
#endif
String str;
str = "abcdef";
printf("%s ",str);  // print "abcdef "
str = "ghijkl";  
printf("%s ",str);  // print "ghijkl "
*(str+3) = 'x';  // error!
printf("%s ",str);

 字符串常量赋值的字符数组可通过数组指针改变成员字符值。这是由于字符数组被常量字符串赋值的原理为:字符数组从常量字符串中依次读取字符,再复制到数组单元中。字符数组指针指向变量区的地址,而并非直接指向常量。依然是进行了只读操作

char str[] = "abcdef";
printf("%s ",str);  // print "abcdef "
*(str+3) = 'x';
printf("%s ",str);  // print "abcxef "

字符串API

 说明:使用字符串API的重要前提是'\0'结束标志的存在。使用字符串API操作不存在'\0'结束标志的字符数组将出现错误。将字符数组中适当位置的字符值替换为'\0'可等效为字符串常量使用字符串API:

char *str1 = "abcde";
char str2[] = {'a','b','c','d','e','\0','f','g','h','i','j','k'};
/* strlen() - 返回字符串中的可见字符(除'\0'之外的字符)个数 */ 
printf("%d ",strlen(str1));  // print "5 "
printf("%d ",strlen(str2));  // print "5 "
/* 比较 str1 与 str2 ,对应位置字符一致,返回 0 */
printf("%d ",strcmp(str1,str2));  // print "0 "

字符串基本操作

以下APIstring.h中声明。

strlen()

/* 返回字符串的长度,即字符串中的 可见字符(除'\0'之外的字符) 个数 */
int strlen(char *str);

// 例:
char *str1 = "123456";
char str2[7] = {'1','2','3','4','5','6'};
str2[6] = '\0';
printf("length of str1 is %d\r\n",strlen(str1)); // print "length of str1 is 6"
printf("length of str2 is %d",strlen(str2)); // print "length of str2 is 6"

strcpy()

/* 将字符串 src 的内容拷贝到 字符数组 dest 中。注意:
   1.src 长度不得超过 dest 的长度,否则可能导致无法预知的错误(编译器不会禁止指针越界访问);
   2.dest 必须指向数组,指向常量字符串将出错(常量字符串的只读性)。
   参数:
   dest - 拷贝目标字符数组 
   src - 拷贝源 
   返回:dest */
char *strcpy(char *dest,char *src);

// 例:
char dest[5];
char *src = "abcde";
char *temp = "fghij";
strcpy(dest,src);
printf("%s ",dest);  // print "abcde "
/* temp指向常量字符串,而常量字符串是只读的 */
printf("%s ",strcpy(temp,src));  // error!

strncpy()

/* 将字符串 src 中的指定 cnt 个字符(索引0~cnt-1)拷贝到 字符数组 dest 中。注意:
   1.cnt 不得大于 dest 的长度,否则可能导致无法预知的错误(编译器不会禁止指针越界访问);
   2.dest 必须指向数组,指向常量字符串将出错(常量字符串的只读性)。
   参数:
   dest - 拷贝目标字符数组 
   src - 拷贝源 
   cnt - 指定字符数 
   返回:dest */
char *strncpy(char *dest,char *src,int cnt);

// 例:
char dest[5];
char *src = "abcdefgh";
strncpy(dest,src,5);
printf(dest);  // print "abcde"

strcat()

/* 将 src 拼接到 dest 尾部。注意:
   1.必须保证 dest 中有足够的空间进行拼接操作,因为 strcat() 通过 结束标志符'\0'
     判断字符串中的尾部位置,如果 dest 中的剩余拼接空间不足('\0'所占空间也需考虑),
     将导致指针越界访问,可能导致无法预知的错误;
   2.dest 必须指向数组,指向常量字符串将出错(常量字符串的只读性)。
   参数:
   dest - 拼接目标指针
   src - 拼接源指针 
   返回:dest */
char *strcat(char *dest,char *src);

// 例:
char dest[10] = "abcde";  // dest中的元素为 {'a','b','c','d','e','\0',0,0,0,0}
char *baddest = "abcde"; 
/* 需要为 '\0' 提供空间  */
char *src = "fghi";
strcat(dest,src);
printf(dest);  // print "abcdefghi"
strcat(baddest,src);  // error!
printf(baddest);

strncat()

/* 将 src 中的指定 cnt 个字符(索引0~cnt-1) 拼接到 dest 尾部。注意:
   1.必须保证 dest 中有足够的空间进行拼接操作,因为 strcat() 通过 结束标志符'\0'
     判断字符串中的尾部位置,如果 dest 中的剩余拼接空间不足('\0'所占空间也需考虑),
     将导致指针越界访问,可能导致无法预知的错误;
   2.dest 必须指向数组,指向常量字符串将出错(常量字符串的只读性)。
   参数:
   dest - 拼接目标指针
   src - 拼接源指针 
   cnt - 指定字符数
   返回:dest */
char *strncat(char *dest,char *src,int cnt);

char dest[10] = "abcde";
char *baddest = "abcde";
char *src = "fghijklm";
/* 需要为 '\0' 提供空间  */
strncat(dest,src,4);
printf(dest);  // print "abcdefghi"
strncat(baddest,src,4);  // error!
printf(baddest);

strcmp()

/* 逐个比较 str1 与 str2 中的字符,直到读取到 '\0' 或 出现不相同字符。注意:
   1.str1 和 str2 既可以是 数组指针 也可以是 常量字符串指针;
   2.str1 或 str2 为 数组指针 时,需要注意加上 '\0' . 
   返回:
   0 - str1 与 str2 比较相同
   !0 - str1 与 str2 比较不同,具体值与C语言标准有关,不建议作准确判断 */
int strcmp(char *str1,char *str2);

// 例:
char *str1 = "abcdef";
char *str2 = "abcdef";
char str3[] = "abcdef";
char str4[] = {'a','b','c','d','e','f'};
char str5[] = {'a','b','c','d','e','f','\0'};
printf("%d ",strcmp(str1,str2));  // print "0 "
printf("%d ",strcmp(str1,str3));  // print "0 "
printf("%d ",strcmp(str1,str4));  // print "-1 "
printf("%d ",strcmp(str1,str5));  // print "0 "
printf("%d ",strcmp(str3,str4));  // print "-1 "
printf("%d ",strcmp(str3,str5));  // print "0 "

strcasecmp()

/* 忽略大小写逐个比较 str1 与 str2 中的字符,
   直到读取到 '\0' 或 出现不相同(忽略大小写)字符。注意:
   1.str1 和 str2 既可以是 数组指针 也可以是 常量字符串指针;
   2.str1 或 str2 为 数组指针 时,需要注意加上 '\0' . 
   返回:
   0 - str1 与 str2 比较相同
   !0 - str1 与 str2 比较不同,具体值与C语言标准有关,不建议作准确判断 */
int strcasecmp(char *str1,char *str2);

// 例:
char *str1 = "abCdEf";
char *str2 = "AbcdeF";
printf("%d",strcasecmp(str1,str2));  // print "0"

strncmp()

/* 逐个比较 str1 与 str2 中的指定 cnt 个字符(索引0~cnt-1),
   直到读取到 '\0' 或 出现不相同字符。注意:
   1.str1 和 str2 既可以是 数组指针 也可以是 常量字符串指针;
   2.str1 或 str2 为 数组指针 时,需要注意加上 '\0' . 
   返回:
   0 - str1 与 str2 比较相同
   !0 - str1 与 str2 比较不同,具体值与C语言标准有关,不建议作准确判断 */
int strncmp(char *str1,char *str2,int cnt);

// 例:
char *str1 = "abcdef";
char *str2 = "abcdhi";
printf("%d ",strncmp(str1,str2,4));  // print "0 "
printf("%d",strncmp(str1,str2,5));  // print "-1"

strncasecmp()

/* 忽略大小写逐个比较 str1 与 str2 中的指定 cnt 个字符(索引0~cnt-1),
   直到读取到 '\0' 或 出现不相同字符(忽略大小写)。注意:
   1.str1 和 str2 既可以是 数组指针 也可以是 常量字符串指针;
   2.str1 或 str2 为 数组指针 时,需要注意加上 '\0' . 
   返回:
   0 - str1 与 str2 比较相同
   !0 - str1 与 str2 比较不同,具体值与C语言标准有关,不建议作准确判断 */
int strncasecmp(char *str1,char *str2,int cnt);

// 例:
char *str1 = "AbCdefghi";
char *str2 = "abcDijcav";
printf("%d ",strncasecmp(str1,str2,4));  // print "0 "
printf("%d",strncasecmp(str1,str2,6));  // print "-4"

strchr()

/* 在 str 中查找 ASCII值 为 val 的字符串。
   注意:
   1.str 既可指向 字符数组,也可指向 字符串常量;
   2.str 为 数组指针 时,需要注意加上 '\0' .
   参数:
   str - 字符串指针
   val - 目标字符的 ASCII 值 
   返回:
   str中包含被查找字符 - 返回该字符第一次出现位置的指针
   str中不含被查找字符 - 返回 NULL,即 void*(0) */
char *strchr(char *str,int val);

// 例:
char *str1 = "abcdefabcdef";
char str2[] = {'a','b','c','d','\0','e','f'};
printf("%s ",strchr(str1,(int)'c'));  // print "cdefabcdef "
printf("%s ",strchr(str2,(int)'c'));  // print "cd "
printf("%s ",strchr(str2,(int)'e'));  // print "(null) "

strrchr()

/* 在 str 中反向查找 ASCII值 为 val 的字符串。
   注意:
   1.str 既可指向 字符数组,也可指向 字符串常量;
   2.str 为 数组指针 时,需要注意加上 '\0';
   3."反向查找" 指 从字符串中第一次出现 结束标志符'\0' 的位置开始 从高索引向低索引 查找。
   参数:
   str - 字符串指针
   val - 目标字符的 ASCII 值 
   返回:
   str中包含该指定字符 - 返回该字符最后一次出现位置的指针
   str中不含该指定字符 - 返回 NULL,即 void*(0) */
char *strrchr(char* str,int val);

// 例:
char *str1 = "abcdefabcdef";
char str2[] = {'a','b','c','d','\0','e','f'};
printf("%s ",strrchr(str1,(int)'c'));  // print "cdef "
printf("%s ",strrchr(str2,(int)'c'));  // print "cd "
/* 从字符串中第一次出现 结束标志符'\0' 的位置开始 从高索引向低索引 查找。 */
printf("%s ",strrchr(str2,(int)'e'));  // print "(null) "

strstr()

/* 在 str 中查找指定的 子字符串sub. 
   注意:
   1.str 与 sub 既可指向 字符数组,也可指向 字符串常量;
   2.str 或 sub 为 数组指针 时,需要注意加上 '\0' . 
   参数:
   str - 源字符串
   sub - 子字符串 
   返回:
   str中包含指定子字符串sub - 返回str中第一次出现sub位置的指针 
   str中不含指定子字符串sub - 返回 NULL,即 void*(0) */
char *strstr(char* str,char *sub);

// 例:
char *str1 = "abcdefabcdef";
char str2[] = {'a','b','c','\0','d','e','f'};
char *str3 = "abc";
char *str4 = "def";
printf("%s ",strstr(str1,str3));  // print "abcdefabcdef "
printf("%s ",strstr(str2,str3));  // print "abc "
printf("%s ",strstr(str2,str4));  // print "(null)"

strpbrk()

/* 查找 str1 与 str2 中的相同字符。 
   注意:
   1.str1 与 str2 既可指向 字符数组,也可指向 字符串常量;
   2.str1 或 str2 为 数组指针 时,需要注意加上 '\0' . 
   参数:
   str1 - 源字符串
   str2 - 查询字符串
   返回:
   str1与str2有相同字符 - 返回 str1 中第一次出现相同字符位置的指针
   str1与str2无相同字符 - 返回 NULL,即 (void*)0 */
char *strpbrk(char *str1,char *str2);

// 例:
char *str1 = "abcdefabcdef";
char *str2 = "xyzbajk";
char str3[] = {'x','y','z','\0','b','a','j','k'};
printf("%s ",strpbrk(str1,str2));  // print "abcdefabcdef "
printf("%s ",strpbrk(str1,str3));  // print "(null) "

strcspn()

/* 查找 str1 与 str2 中的相同字符。 
   注意:
   1.str1 与 str2 既可指向 字符数组,也可指向 字符串常量;
   2.str1 或 str2 为 数组指针 时,需要注意加上 '\0' . 
   参数:
   str1 - 源字符串
   str2 - 查询字符串
   返回:
   str1与str2有相同字符 - 返回 str1 中第一次出现相同字符位置的索引
   str1与str2无相同字符 - 返回 str1的字符个数,即 最大索引+1 */
int strcspn(char *str1,char *str2);

// 例:
char *str1 = "abcdefabcdef";
char *str2 = "xyzbajk";
char str3[] = {'x','y','z','\0','b','a','j','k'};
printf("%d ",strcspn(str1,"f"));  // print "5 "
printf("%d ",strcspn(str1,str2));  // print "0 "
printf("%d ",strcspn(str1,str3));  // print "12 "

strspn()

/* 查找 str1 中 str2 不包含 的字符。 
   注意:
   1.str1 与 str2 既可指向 字符数组,也可指向 字符串常量;
   2.str1 或 str2 为 数组指针 时,需要注意加上 '\0' . 
   参数:
   str1 - 源字符串
   str2 - 查询字符串
   返回:
   str1中有str2不包含的字符 - 返回 str1 中第一次出现str2不包含字符位置的索引
   str2包含str1中的所有字符 - 返回 str1的字符个数,即 最大索引+1 */
// 例:
char *str1 = "abcdefabcdef";
char *str2 = "abcjklmn";
char str3[] = {'a','b','\0','c','j','k','l','m','n'};
char *str4 = "abcdef";
/* str2中不包含 'd' */
printf("%d ",strspn(str1,str2));  // print "3 "
/* str3中包含 'c',但 '\0' 出现在 'c' 之前,因而str3中实际不包含 'c' */
printf("%d ",strspn(str1,str3));  // print "2 "
/* str4中包含str1中的所有字符 */
printf("%d ",strspn(str1,str4));  // print "12 "

字符串转换

以下APIstdlib.h中声明。

字符串转换为数值类型

strod()

/* 将字符串 str 中的 有效数字部分 转换为 double 类型。
   具体过程是:
   strtod()逐个字符的扫描 str,跳过 str 开头的空格,读取到 '+'/'-'或数字 之后开始转换,
   读取到 '\0'或非数字 之后结束转换。
   str中的有效数字部分可以包含'+','-','.','e'(指数),'E'(指数)
   参数:
   str - 目标字符串指针; 
   endptr(char*型指针,指向char型指针变量) - 如果 endptr 不为 NULL,
     则将 str 中有效数字部分之后的 非有效数字部分的指针数据 存入 endptr 所指向的内存中。
     一般不需要处理之后的无效字符,因此此参数常常直接传入 NULL .
   返回:
   转换成功 - 返回转换后的 double 类型数据
   转换失败 - 返回 0 */
double strtod(char *str,char **endptr);

// 例:
char *str1 = "-1.23E-2xyz";
char *str2 = "   -1.23E-2xyz";
char *str3 = "a1.23E-2xyz";
/* 不可定义为 char **endptr;
   根据定义,如果想要 endptr 存储尾部无效字符,
   endptr 不可为 NULL , 而指针变量必须 NULL 初始化。
   定义为 char *endptr; 再使用 &endptr 取 char**指针 可避免此问题 */
char *endptr = NULL;
double dest;

dest = strtod(str1,&endptr);
printf("%lf ",dest);  // print "-0.012300 "
printf("%s ",endptr);  // print "xyz "
/* str开头可以为空格 */
dest = strtod(str2,&endptr);
printf("%lf ",dest);  // print "-0.012300 "
printf("%s ",endptr);  // print "xyz "
/* str3开头为字符'a',不是有效字数字部分 */
dest = strtod(str3,&endptr);
/* 转换失败,返回 0 */
printf("%lf ",dest);  // print "0.000000 "
printf("%s ",endptr);  // print "a1.23E-2xyz "

strtof()

/* 将字符串 str 中的 有效数字部分 转换为 float 类型 */
float strtof(char *str,char **endptr);

// 例:
char *str = "  +1.2e-1 is float data";
char *endptr = NULL;
float dest;
dest = strtof(str,&endptr);
printf("%f ",dest);  // print "0.120000 "
printf("%s ",endptr);  // print " is float data "

strtol()

/* 将字符串 str 中的 有效数字部分 按照指定指定进制 radix 转换为 long 类型。
   具体过程是:
   strtol()逐个字符的扫描 str,跳过 str 开头的空格,读取到 '+'/'-'或有效进制数 之后开始转换,
   读取到 '\0'或非有效进制数 之后结束转换。
   str中的有效数字部分可以包含'+','-',"0x","0X",有效进制数(例如16进制中的'f'/'F')
   参数:
   str - 目标字符串指针; 
   endptr(char*型指针,指向char型指针变量) - 如果 endptr 不为 NULL,
     则将 str 中有效数字部分之后的 非有效数字部分的指针数据 存入 endptr 所指向的内存中。
     一般不需要处理之后的无效字符,因此此参数常常直接传入 NULL .
   radix - 进制数,取值范围是 2~36,也可为 0 , 
     为 0 时识别为 10进制 或 16进制(仅当出现"0x"/"0X"时)。 
   返回:
   转换成功 - 返回转换后的 long 类型数据
   转换失败 - 返回 0 */
long strtol(char *str,char **endptr,int radix);

// 例:
char *str1 = "01100101xyz";
char *str2 = "0770065470";
char *str3 = "123456789";
char *str4 = "0xffedf0";
char *str5 = "  -ddfacbbghi";
char *endptr = NULL;
long dest;

dest = strtol(str1,&endptr,2);
printf("%ld ",dest);  // print "101 "  
printf("%s ",endptr);  // print "xyz "

printf("%ld ",strtol(str2,NULL,8));  // print "132148024 "
printf("%ld ",strtol(str3,NULL,10));  // print "123456789 "
printf("%ld ",strtol(str4,NULL,16));  // print "16772592 "

dest = strtol(str5,&endptr,16);
printf("%ld ",dest);  // print "-232762555 "
printf("%s ",endptr);  // print "ghi "

atoi()

/* 将字符串 str 中的 有效数字部分 转换为 int 类型。
   具体过程是:
   atoi()逐个字符的扫描 str,跳过 str 开头的空格,读取到 '+'/'-'或数字 之后开始转换,
   读取到 '\0'或非数字 之后结束转换。
   str中的有效数字部分可以包含'+','-','
   参数:
   str - 目标字符串指针
   返回:
   转换成功 - 返回转换后的 int 类型数据
   转换失败 - 返回 0 */
int atoi(char *str);

// 例:
char *str1 = "  -13222abc";
char *str2 = "0xff00f";
/* 无效部分将被丢弃 */
printf("%d ",atoi(str1));  // print "-13222 "
/* 仅识别 10进制 */
printf("%d ",atoi(str2));  // print "0 "

atof()

/* 将字符串 str 中的 有效数字部分 转换为 double 类型。
   具体过程是:
   atof()逐个字符的扫描 str,跳过 str 开头的空格,读取到 '+'/'-'或数字 之后开始转换,
   读取到 '\0'或非数字 之后结束转换。
   str中的有效数字部分可以包含'+','-','.','e','E'
   参数:
   str - 目标字符串指针
   返回:
   转换成功 - 返回转换后的 int 类型数据
   转换失败 - 返回 0 */
double atof(char *str);

// 例:
char *str1 = "12.03cgcg";
char *str2 = "1.23E-4";
/* 无效部分将被丢弃 */
printf("%f ",atof(str1));  // print "12.030000 "
printf("%f ",atof(str2));  // print "0.000123 "

atol()

/* 将字符串 str 中的 有效数字部分 转换为 long 类型。*/
long atol(char *str);

数值类型转换为字符串

itoa()

/* 将指定 int型 数据按照指定的进制 radix 转换为字符串,保存在 数组dest 中。
   注意:
   必须保证 数组dest 有足够的空间,包括存储 '\0','+','-' 的空间,
   否则将导致指针越界访问,可能导致无法预知的错误。
   参数:
   val - 目标int类型数据 
   dest - 数组指针
   radix - 进制数
   返回:dest */
char *itoa(int val,char *dest,int radix);

// 例:
int val = 1234;
char dest[16] = {0};
itoa(val,dest,2);
printf("%s ",dest);  // print "10011010010 "
itoa(val,dest,8);  
printf("%s ",dest);  // print "2322 "  
itoa(val,dest,10);
printf("%s ",dest);  // print "1234 "
itoa(val,dest,16);
printf("%s ",dest);  // print "4d2 "

ltoa()

/* 将指定 long型 数据按照指定的进制 radix 转换为字符串,保存在 数组dest 中。*/
char *ltoa(long val,char *dest,int radix);

ultoa()

/* 将指定 unsigned long型 数据按照指定的进制 radix 转换为字符串,保存在 数组dest 中。*/
char *ultoa(unsigned long val,char *dest,int radix);

ecvt()

/* 将指定 double型 数据 val 转换为指定有效数字位数 num 的不带小数点和符号的纯数字字符串
   参数:
   val - 目标double型数据,可以是使用 e/E 表示的指数形式,例:-1.23E-5
   num - 指定数字位数,若val中的数字多于num,舍弃多的部分(四舍五入原则),少于num则补0 
   decptr - 存放小数点位置数据(小数点在数字字符串中第几个数字之后)的int指针。
     (*decptr)>0,表示小数点在数字字符串中第一个数字的 右边(即val>1,例如1.23);
     (*decptr)=0,表示小数点在数字字符串中第一个数字的 左边相邻(即0.1=<val<1,例如0.123)
     (*decptr)<0,表示小数点在数字字符串中第一个数字的 左边非相邻(即val<0.1,例如0.0123)
   sigptr - 存放表示数据符号的int指针,为 0 表示数据为正数,!0 为负数 
   返回:转换结果指针 */
char *ecvt(double val,int num,int *decptr,int *sigptr);

// 例:
double val1 = 12.3006;
double val2 = 12.3004;
double val3 = 0.123;
double val4 = -1.23E-2;
int dec;
int sig;
char *str;

str = ecvt(val1,5,&dec,&sig);
/* 四舍五入 */
printf("val1 is %s,",str);  // print "val1 is 12301,"
/* 小数点在数字字符串的第2个数字右边 */
printf("dec is %d,",dec);  // print "dec is 2,"
/* val1为正数 */
printf("sig is %d\r\n",sig);  // print "sig is 0"

str = ecvt(val2,5,&dec,&sig);
/* 四舍五入 */
printf("val2 is %s,",str);  // print "val2 is 12300,"
/* 小数点在数字字符串的第2个数字右边 */
printf("dec is %d,",dec);  // print "dec is 2,"
/* val2为正数 */
printf("sig is %d\r\n",sig);  // print "sig is 0"

str = ecvt(val3,5,&dec,&sig);
printf("val3 is %s,",str);  // print "val3 is 12300,"
/* 小数点在数字字符串中第一个数字的 左边相邻 */
printf("dec is %d,",dec);  // print "dec is 0,"
/* val3为正数 */
printf("sig is %d\r\n",sig);  // print "sig is 0"

str = ecvt(val4,10,&dec,&sig);
printf("val4 is %s,",str);  // print "val4 is 1230000000,"
/* 小数点在数字字符串中第一个数字的 左边非相邻 */
printf("dec is %d,",dec);  // print "dec is -1,"
/* val4为负数 */
printf("sig is %d\r\n",sig);  // print "sig is 1"

fcvt()

/* 将指定 double型 数据 val 转换为指定精度位数 num 的不带小数点和符号的纯数字字符串。
   "指定精度位数num" 指 小数位数为num , 例 123.123, num为5:12312300, num为1:1231
   参数:
   val - 目标double型数据,可以是使用 e/E 表示的指数形式,例:-1.23E-5
   num - 指定精度数,若val的精度高于num,舍弃多的部分(四舍五入原则),低于num则补0 
   decptr - 存放小数点位置数据(小数点在数字字符串中第几个数字之后)的int指针。
     (*decptr)>0,表示小数点在数字字符串中第一个数字的 右边(即val>1,例如1.23);
     (*decptr)=0,表示小数点在数字字符串中第一个数字的 左边相邻(即0.1=<val<1,例如0.123)
     (*decptr)<0,表示小数点在数字字符串中第一个数字的 左边非相邻(即val<0.1,例如0.0123)
   sigptr - 存放表示数据符号的int指针,为 0 表示数据为正数,!0 为负数 
   返回:转换结果指针 */
char *fcvt(double val,int num,int *decptr,int *sigptr);

// 例:
double val1 = 123.123;
double val2 = 123.166;
double val3 = 0.123;
double val4 = -1.23E-5;
int dec;
int sig;
char *str;

str = fcvt(val1,5,&dec,&sig);
/* 原数精度不够,补0 */
printf("val1 is %s,",str);  // print "val1 is 12312300,"
/* 小数点在数字字符串中第3个数字的右边 */
printf("dec is %d,",dec);  // print "dec is 3,"
/* 正数 */
printf("sig is %d\r\n",sig);  // print "sig is 0"

str = fcvt(val2,1,&dec,&sig);
/* 原精度太高,四舍五入 */
printf("val2 is %s,",str);  // print "val2 is 1232,"
/* 小数点在数字字符串中第3个数字的右边 */
printf("dec is %d,",dec);  // print "dec is 3,"
/* 正数 */
printf("sig is %d\r\n",sig);  // print "sig is 0"

str = fcvt(val3,5,&dec,&sig);
/* 原数精度不够,补0 */
printf("val3 is %s,",str);  // print "val3 is 12300,"
/* 小数点在数字字符串中第1个数字的左边相邻 */
printf("dec is %d,",dec);  // print "dec is 0,"
/* 正数 */
printf("sig is %d\r\n",sig);  // print "sig is 0"

str = fcvt(val4,5,&dec,&sig);
/* 原数精度太高,四舍五入 */
printf("val4 is %s,",str);  // print "val4 is 1,"
/* 小数点在数字字符串中第1个数字的左边非相邻 */
printf("dec is %d,",dec);  // print "dec is -4,"
/* 负数 */
printf("sig is %d\r\n",sig);  // print "sig is 1"

gcvt()

/* 将指定 double型 数据 val 转换为指定有效数字位数 num 的 带小数点和符号的数字字符串,
   结果保存在 dest 中。
   注意:
   必须保证 数组dest 有足够的空间,包括存储 '\0','+','-','e','.' 的空间,
   否则将导致指针越界访问,可能导致无法预知的错误。
   参数:
   val - 目标double型数据,可以是使用 e/E 表示的指数形式,例:-1.23E-5
   num - 指定有效数字位数,若val的有效位数多于num,舍弃多的部分(四舍五入原则),少于num则补0 
   dest - 保存结果的数组指针
   返回:dest */
char *gcvt(double val,int num,char *dest);

// 例:
double val1 = 123.125;
double val2 = 0.000123;
double val3 = -123.123E-5;
/* 必须保证足够的空间 */
char dest[15];

gcvt(val1,5,dest);
/* 四舍五入 */
printf("%s ",dest);  // print "123.13 "

gcvt(val2,5,dest);
/* 转换结果中的 '+','-','.','e' 不占有效位 */
printf("%s ",dest);  // print "1.23e-004 "

gcvt(val3,9,dest);
/* 转换结果中的 '+','-','.','e' 不占有效位 */
printf("%s ",dest);  // print "-1.23123e-003 "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值