【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)&&三种strlen模拟实现1:https://developer.aliyun.com/article/1474747
总结:我们可以把可变参数(...)设置为整数num,(const char * format)格式是==“%d”,存储进大小为size_t n的目标字符数组str==中就可以解决了。
上代码:
#include <stdio.h> int main() { int num = 123456;//定义一个整数num char str[10] ;//字符数组str作为目标缓冲区 int len = snprintf(str, sizeof(str), "%d", num); //调用snprintf进行格式化转换,并用len接收返回值 printf("%d\n", len);//查看他返回的写入字符串的个数 if (len < 0) { printf("编码错误\n"); return -1; } if (len >= sizeof(str)) { printf("截断,数字长度大于缓冲区大小\n"); } else { printf("字符串转换成功: %s\n", str); printf("字符串写入成功且第二个元素是: %c\n", str[1]); } return 0; }
代码运行:
在代码中,我没有给字符数组str赋值 char str[10] ;//字符数组str作为目标缓冲区,在整数123456调试中我们可以看到str[6]=='\0'
'\0'哪里来的呢?
我们通过前面知道snprintf函数的返回值表示实际写入目标字符串的字符数,但不包括结尾的null字符’\0’。
至于null字符'\0'是怎么来的,snprintf在写入字符串时,会自动在结尾添加一个null字符'\0’,用来标识字符串的结束。
整数"123456"转换为字符串,需要6个字符加1个null字符,总长度是7。
因此我们需要在目标字符串内存中预留了null字符所占的空间
int num = 1234567890;//将num重新定义10个整数 char str[10] ;//字符数组str作为目标缓冲区 • 1 • 2
因此我们需要在目标字符串内存中预留了null字符所占的空间,不然会发生截断
💯 💯 💯strlen的使⽤
size_t strlen ( const char * str ); • 1
• 字符串以
'\0'
作为结束标志,strlen
函数返回的是在字符串中'\0'
前⾯出现的字符个数(不包含'\0'
)。• 参数指向的字符串必须要以
'\0'
结束。• 注意函数的返回值为
size_t
,是⽆符号的( 易错 )•
strlen
的使⽤需要包含头⽂件
代码实现:
#include <stdio.h> #include <string.h> int main() { char arr1[] = "abcdef";//[a b c d e f \0] char arr2[] = { 'a', 'b', 'c' ,'\0'};//[a b c] size_t len = strlen(arr2); printf("%zd\n", len); return 0; }
有个易错题:
#include <stdio.h> #include <string.h> int main() { const char* str1 = "abcdef";//6 const char* str2 = "bbb";//3 if (strlen(str2) - strlen(str1) > 0) { printf("str2>str1\n"); } else { printf("srt1>str2\n"); } return 0; }
答案是什么呢?
运行启动:
为什么呢?
strlen
返回的字符串长度类型是size_t
,它是一个无符号整数类型。
str1
长度为str2
长度为3
strlen(str2) - strlen(str1)
计算为3 - 6
,结果是-3
- 但是
-3
作为size_t
类型,它是一个无符号整数,所以它的值实际上是大于0的,所以打印的是"str2>str1"
。
注意:
size_t是一个无符号整数类型
例如在32
位系统中:
size_t
最大值为2^32 - 1
-3
作为size_t,
它的值就是2^32 - 1 - 3他的值远远大于0.
💯 💯 💯 💯 strlen的3种模拟实现方式
- 创建临时变量
count
#include <stdio.h> #include <string.h> #include <assert.h> size_t my_strlen1(const char* str) { size_t count = 0; assert(str != NULL); while (*str) { count++; str++; } return count; }
2.指针减指针
start
指针记录起始位置,str
指针遍历字符串,返回二者差值即为长度。
size_t my_strlen2(const char* str) { assert(str); const char* start = str; while (*str) { str++; } return str - start;//两指针相减得到的是中间的元素个数 }
3.函数递归遍历(不使用临时变量,求字符串长度)
size_t my_strlen(const char* str) { if (*str == '\0') return 0; else return 1 + my_strlen(str + 1); } int main() { char arr[] = "abcdef"; size_t len = my_strlen(arr); printf("%zd\n", len); return 0; }
例如,递归abcdef my_strlen("abcdef"); 1+my_strlen("bcdef"); 1+1+my_strlen("cdef"); 1+1+1+my_strlen("def"); 1+1+1+1+my_strlen("ef"); 1+1+1+1+1+my_strlen("f"); 1+1+1+1+1+1+my_strlen(""); 1+1+1+1+1+1+0;
📝总结
通过学习字符分类函数、字符串转换函数和字符串长度计算的原理和用法,我们可以更好地理解字符和字符串的处理方式,并能够灵活运用这些函数进行字符和字符串的处理。这些函数在实际的开发中经常会用到,掌握它们的使用方法对于提高开发效率和代码质量都很重要。