概述
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 "
字符串基本操作
以下API
在string.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 "
字符串转换
以下API
在stdlib.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 "