#include<stdio.h>
#include<assert.h>
#include<ctype.h>
//strcpy(p, p1) 複製字符串
///strncpy(p, p1, n) 複製指定長度字符串
char *My_strcpy1(char *des, const char *src, int len1, int len2)
{
char *p = des;
assert((len1 >= len2)&&(*src != NULL));
while(*src != '\0')
{
*des = *src;
des++;
src++;
}//while(*des++ = *src++)
*des = '\0';
return p;
}
//拷貝
char *My_strcpy2(char *des, const char *src, int len1, int len2)
{
assert((len1 >= len2)&&(*src != NULL));
int i;
for(i = 0; src[i] != '\0'; i++)
{
des[i] = src[i];
}
des[i] = '\0';
return des;
}
//拷貝
char *My_strncpy(char *des, const char *src, int len1, int len2, int n)
{
assert((len1 >= len2)&&(*src != NULL));
int i;
for(i = 0; src[i] != '\0' && i < n; i++)
{
des[i] = src[i];
}
return des;
}
//拷貝
//strlen(p) 取字符串長度
int My_strlen(const char *src)
{
int temp = 0;
while(*src != '\0')
{
temp++;
src++;
}
return temp;
}
//長度
//strcmp(p, p1) 比較字符串
//strncmp(p, p1, n) 比較指定長度字符串
int My_strcmp(const char *str1, const char *str2)
{
assert((*str1 != NULL)&&(*str2 != NULL));
int temp;
while((temp = *str1 - *str2) == 0)
{
str1++;
str2++;
}
return temp;
}
//比較
int My_strncmp(const char *str1, const char *str2, int n)
{
assert((*str1 != NULL)&&(*str2 != NULL));
int i;
int temp;
for(i = 0; str2[i] != '\0' && i < n; i++)
{
while((temp = *str1 - *str2) == 0)
{
str1++;
str2++;
}
}
return temp;
}
//比較
//strcat(p, p1) 附加字符串
//strncat(p, p1, n) 附加指定長度字符串
char *My_strcat(char *des, const char *src)
{
assert(src != NULL);
char *p = des;
while(*des != '\0')
{
des++;
}
while(*src != '\0')
{
*des++ = *src++;
}
*des = '\0';
return p;
}
//字符串連接
char *My_strncat(char *des, const char *src, int n)
{
assert(src != NULL);
char *p = des;
while(*des != '\0')
{
des++;
}
for(int i = 0; *src != '\0' && i < n; i++)
{
*des++ = *src++;
}
*des = '\0';
return p;
}
//字符串連接
void Func(char *str1)
{
assert(*str1 != NULL);
int flag = 0;
int word = 0;
int count = 0;
while(*str1 != '\0')
{
if(*str1 == ' ')
{
flag = 0;
}
if(isalpha(*str1))
{
count++;
if(*str1 != ' '&& flag == 0)
{
flag = 1;
word++;
}
}
str1++;
}
printf("字符個數 %d\n", count);
printf("單詞量 %d\n", word);
}
//字符個數、單詞量
char *My_itoa(int num, char *str)
{
char *p = str;
int i = 0;
int j;
char temp;
int flag = 1;
while(num != 0)
{
if(num < 0)
{
num = -num;
flag = -1;
}
str[i] = num % 10 + '0';
num = num / 10;
i++;
}
if(flag < 0)
{
str[i++] = '-';
}
str[i] = '\0';
i--;
for(j = 0; j < i; j++, i--)
{
temp = str[j];
str[j] = str[i];
str[i] = temp;
}
return p;
}
//整數轉字符
int My_atoi(const char *str)
{
assert(*str != NULL);
int flag = 1;
//int i;
int num = 0;
while(isspace(*str) == ' ')
{
str++;
}
if(*str == '-')
{
flag = -1;
str++;
}
else if(*str == '+')
{
str++;
}
while(*str != '\0' && isdigit(*str))
{
num = num * 10 + *str - '0';
str++;
}
return num*flag;
}
//字符轉整數
int main()
{
char str[30];
char *str4 = "1a2b3";
char *str5 = "-123";
char str1[30] = "ab cd ef fe ";
char *str3 = " ab cd ef";
char *str2 = "tulun";
int len1 = sizeof(str1)/sizeof(str1[0]);
int len2 = sizeof(str2)/sizeof(str2[0]);
printf("My_strcpy1 %s\n", My_strcpy1(str1, str2, len1, len2));
printf("My_strcpy2 %s\n", My_strcpy2(str1, str2, len1, len2));
printf("My_strncpy %s\n", My_strncpy(str1, str2, len1, len2, 3));
printf("My_strlen %d\n", My_strlen(str1));
printf("My_strcmp %d\n", My_strcmp(str3, str2));
printf("My_strncmp %d\n", My_strncmp(str3, str2, 3));
printf("My_strcat %s\n", My_strcat(str1, str2));
printf("My_strncat %s\n", My_strncat(str1, str2, 2));
printf("My_itoa %s\n", My_itoa(-123, str));
printf("My_atoi %d\n", My_atoi(str4));
printf("My_atoi %d\n", My_atoi(str5));
Func(str1);
Func(str3);
getchar();
return 0;
}
1、返回值的作用:鏈式表達式
int len = strlen(strcpy(str1, str2));
2、關於const:固定離其最近的
const在 * 之前表示內容不變;
const在 * 之後表示指針不變;
const char *str1 = char const *str2 = "abc";//常量字符串,不能修改指向內容
char *const str2 = "def";//常量指針
str1 = str2;
3、assert函數:斷言,準確快速地找到錯誤(debug條件下)
#include <assert.h>
void assert( int expression );
assert的作用是現計算表達式 expression ,如果其值爲假(即爲0),那麼它先向stderr打印一條出錯信息,然後通過調用 abort 來終止程序運行。
4、
c語言中的isalpha,isdigit,islower,isupper等一系列函數
5、*(str + 1) 與 str[1] 存取效率:
(1)*(str + 1)
str本身地址—>取出str存放數據地址—>訪問數據
(2)str[1]
str的地址—>str + 1
6、strtok函數
char *strtok(char s[], const char *delim);
1)功能:分解字符串爲一組字符串。s爲要分解的字符串,delim爲分隔符字符串,所有delim中包含的字符都會被濾掉,並將被濾掉的地方設爲一處分割的節點。
2)掃描字符串s,找到delim(假設指定” “)—–>將s中找到的” “變成0,
(1)第一次調用:
strtok(str, " "); //先從原串首字符開始掃描(strtok通過自定義分隔符分隔字符串),
(2)第二次及多次調用:
strtok(NULL, " "); //再從判斷後指針指向的位置開始判斷
3)返回值:
每次調用成功則返回指向被分割出片段的指針;
當查找不到delim中的字符時,返回NULL。
7、越界問題:
(1)不檢驗’\0’是否屬於其拷貝或計算的字符串對象
strcpy()函數是針對C風格字符串進行拷貝的,即遇’\0’而停止拷貝;
strlen()函數只拷貝字符串的實際顯示的字符長度,而不包括’\0’字符
(2)不考慮內存重疊問題