字符串转内存c语言,【一起学C】C语言面试题必考:字符串操作函数,内存操作函数实现...
本帖最后由 奉聰 于 2017-1-25 14:54 編輯
*******前言*******
我數一下,我發了幾個帖子,1、2、3?
哈哈哈,沒幾個哈,感謝吾愛,讓我學到了很多,樂于分享,共同進步!
最近也是在學c語言,也看了少許面試題
指針,數據結構,字符串操作肯定是重點
今天分享出來的是,一些字符串操作函數和一些內存操作函數的手動實現
內容應該不難,如有錯誤還請朋友們指出,我會認真改正的,希望一起學習進步
*******目錄*******
字符串常見函數:
strlen、strcmp、strcpy、strlwr、strrev、strset、strstr、strupr、itoa、atoi、atof、ftoa
(希望初學者能夠嘗試用下標訪問和指針訪問兩種方式實現)
內存操作少許函數:
memccpy、memchr、memcpy、memicmp、memmove、memset
(希望讀者能夠認真手動實現)
當然實際開發中,這些函數直接調用就行了,
但是面試的時候,這是基礎知識,這是考察你的基本功 和 砍你工資的大斧
因為簡單,所以代碼注釋少,有疑惑的請告訴我,樂于交流
*******字符串函數*******
1.strlen:計算字符串長度(不包含'\0')
實現想法:遍歷字符串,直到'\0'結束
[C] 純文本查看 復制代碼#include
#include
#include
//指針法
unsigned int mystrlenaddr(const char * str) //為什么使用const char,我們只計數不對原數據進行改變
{
int length = 0; //長度初始化為0
while (*str++)
{
length++;
}
return length;
}
void main()
{
char * str = "fengcong is fucking too handsome"; //32個
//printf("%d\n", strlen(str));
printf("%d\n", mystrlenaddr(str));
system("pause");
}
2.strcmp:比較字符串大小(一般用于字符串排序)
實現想法:依次從字符串開始一直找到不同的那個字符進行比較,得出大小
[C] 純文本查看 復制代碼#include
#include
#include
//掌握指針法
int mystrcmp(char const * str1, const char * str2)
{
while (*str1 == *str2 && *str1 != '0') //一直找到兩個字符串不同的地方
{
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
else if (*str1 < *str2)
return -1;
else
return 0;
}
void main()
{
char * str = "feng1";
char * str1 = "feng2";
//printf("%d\n", strcmp(str, str1));
printf("%d\n", mystrcmp(str, str1));
system("pause");
}
3.strcpy:用于字符串復制(復制包含'\0')
實現想法:一直復制到'\0'結束
[C] 純文本查看 復制代碼#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
//指針法
char * mystrcpyaddr(char * dest, const char * source)
{
if (dest == NULL || source == NULL)
{
return NULL; //如果目的操作或者源為空,那么久直接返回
}
while (*dest++ = *source++) //裝X寫法
;
return dest;
}
//下標法
char * mystrcpyindex(char * dest, const char * source)
{
if (dest == NULL || source == NULL)
{
return NULL; //如果目的操作或者源為空,那么久直接返回
}
int i = 0;
while (source != '\0')
{
dest = source;
i++;
}
dest = source; //因為要把最后的\0拷貝過去
return dest;
}
void main()
{
char * str = "fengcong is fucking too handsome";
char str1[100]; //目的字符數組
//strcpy(str1, str);
//printf("%s\n", str1);
mystrcpyindex(str1, str);
printf("%s\n", str1);
system("pause");
}
4.strlwr:大寫轉小寫
實現想法:遍歷字符串,遇到大寫轉為小寫
[C] 純文本查看 復制代碼#include
#include
#include
char * mystrlwr(char * str)
{
char * p1 = str;
while (*p1)
{
if (*p1 >= 'A' && *p1 <= 'Z')
{
*p1 += 32;
}
p1++;
}
return str;
}
void main()
{
char str[50] = "FENGCONG IS FUCKING TOO HANDSOME";
//printf("%s\n", _strlwr(str));
printf("%s\n", mystrlwr(str));
system("pause");
}
5.strrev:字符串逆轉
實現想法:頭首交換,直到中間
[C] 純文本查看 復制代碼#include
#include
#include
char * mystrrev(char * str)
{
char * p2 = str;
char * p1 = str;
while (*p1++)
{
;
}
p1 -= 2; //回到最后一個字符
while (p1 - p2 >= 1)
{
char temp = *p1;
*p1 = *p2;
*p2 = temp;
p2++;
p1--;
}
return str;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
//_strrev(str);
//printf("%s\n", str);
printf("%s\n",mystrrev(str));
system("pause");
}
6.strset:將字符串全部設成某字符
實現想法:遍歷字符串,每個字符設置某字符,直至'\0'
[C] 純文本查看 復制代碼#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
char * mystrset(char * str, int value)
{
char * p1 = str;
while (*p1)
{
*p1 = value;
p1++;
}
return str;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
//printf("%s\n", _strset(str, 'A'));
printf("%s\n", mystrset(str, 'A'));
system("pause");
}
7.strstr:尋找母串中是否存在某個子串(稍難)
實現想法:依次比對
[C] 純文本查看 復制代碼#include
#include
#include
//下標 法
char * mystrstrindex(char * const momstr, const char * const sonstr)//前者指針指向的數據可變,但是指針不可變,后者都不可變
{
int momlen = strlen(momstr); //母串的長度
int sonlen = strlen(sonstr); //子串的長度
for (int i = 0; i < (momlen - sonlen); i++) //從0開始循環母串,到momlen-sonlen停止
{
int flag = 1;
for (int j = 0; j < sonlen; j++)
{
if (momstr[i + j] != sonstr[j])
{
flag = 0;
break; //如果出現不相等就 退出循環,繼續從下面一個尋找
}
}
if (flag)
{
return (&momstr);
}
}
return NULL;
}
//指針法
char * mystrstraddr(char * const momstr, const char * const sonstr)
{
char * mstr = momstr; //母串
while (*mstr)
{
char * sstr = sonstr; //子串
char * momnowstr = mstr; //記錄現在母串的位置
int flag = 1;
while (*sstr != 0)
{
if (*sstr != *momnowstr || *momnowstr == '0')
{
flag = 0;
break;
}
momnowstr++;
sstr++;
}
if (flag)
{
return mstr;
}
mstr++; //母串對比位置+1
}
return NULL;
}
void main()
{
char * str = "fengcong is too fucking handsome";
//printf("%p", strstr(str, "fengcong"));
//printf("%p", mystrstrindex(str, "engcong"));
printf("%p", mystrstraddr(str, "some"));
system("pause");
}
8.strupr:小寫轉大寫
實現想法:依次遍歷,遇到小寫轉為大寫
[C] 純文本查看 復制代碼#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
char * mystrupr(char * str)
{
char * p1 = str;
while (*p1)
{
if (*p1 >= 'a' && *p1 <= 'z')
{
*p1 -= 32;
}
p1++;
}
return str;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
//printf("%s\n", _strupr(str));
printf("%s\n", mystrupr(str));
system("pause");
}
9.itoa:整數轉字符串
[C] 純文本查看 復制代碼#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
char * myitoa(int value, char * str)
{
char * pstr = str; //str本身不能改變,一會要返回str
if (value < 0)
{
*pstr = '-';
pstr++;
value *= -1; //轉變為正數處理
}
int wei = 1; //數至少一位
int ivalue = value; //用于測試長度
while ((ivalue /= 10) != 0)
{
wei++;
}
pstr += wei-1;
while (value % 10 != 0)
{
*pstr-- = (value % 10)+'0';
value /= 10;
}
return str;
}
void main()
{
int num = -45644;
char str[20] = { 0 };
printf("%s", myitoa(num, str));
system("pause");
}
10.atoi:字符串轉整數(遇到非數字字符結束)
[C] 純文本查看 復制代碼#include
#include
#include
int myatoi(const char * str)
{
if (str == NULL)
{
return 0;
}
int num = 0; //需要返回的值
int flag = 1; //記錄正負號
if (*str == '-')
{
flag = -1;
str++;
}
else if (*str == '+')
{
str++;
}
while (*str >= '0' && *str <= '9')
{
num= (num * 10 + (*str - '0'));
str++;
}
return num*flag;
}
void main()
{
char str[20] = "-57124";
int num = 0;
printf("%d\n",myatoi(str));
system("pause");
}
11.atof:字符串轉浮點數
[C] 純文本查看 復制代碼#include
#include
#include
double myatof(char const * str)
{
if (str == NULL)
return 0;
//首先判斷有無符號位
int flag = 1;
if (*str == '-')
{
flag = -1;
str++;
}
if (*str == '+')
{
str++;
}
int zhengshu = 0; //存儲整數部分
while (*str >= '0' && *str <= '9')
{
zhengshu = zhengshu * 10 + (*str - '0');
*str++;
}
//整數部分循環完了
double xiaoshu = 0.0; //存儲小數部分
//因為不明符號停止整數循環
if (*str != '.')
{
return (flag * zhengshu);
}
else //代表遇到. 結束
{
str++; //指向小數部分第一位
double i = 0.1;
while (*str >= '0' && *str <= '9')
{
xiaoshu = xiaoshu + (*str - '0')*i;
i /= 10;
str++;
}
return flag *(zhengshu + xiaoshu);
}
}
void main()
{
char str[20] = "2.1554";
double db = 0.0;
printf("%lf\n", myatof(str));
system("pause");
}
12.ftoa:浮點數轉字符串(浮點數存儲不準確,可能有少許誤差)
[C] 純文本查看 復制代碼#include
#include
#include
char * myftoa(double db, char * str)
{
char * pstr = str;
//先判斷 符號位
if (db < 0)
{
*pstr = '-';
db *= -1; //轉為正數處理
pstr++;
}
//整數部分
int zhengshu = (int)db;
int izhengshu = zhengshu; //犧牲于記錄整數長度
int wei = 1; //整數部分至少一位
while ((izhengshu /= 10) != 0)
{
wei++;
}
pstr += wei - 1;
for (int i = 0; i < wei; i++)
{
*pstr-- = zhengshu % 10 + '0';
zhengshu /= 10;
}
pstr += (wei+1);
*pstr = '.';
pstr++;
//小數部分
double xiaoshu = db - (int)db;
for (int i = 0; i < 6; i++)
{
*pstr++ = (int)(xiaoshu * 10) + '0';
xiaoshu = xiaoshu * 10 - (int)(xiaoshu * 10);
}
return str;
}
void main()
{
double db = -2.11;
char str[20] = { 0 };
printf("%s\n", myftoa(db,str));
system("pause");
}
*******內存操作函數*******
1.memccpy:內存拷貝,直到一個值結束
[C] 純文本查看 復制代碼#include
#include
#include
//下標法
void * mymemccpybyindex(void * dest, const void * sor,int val, size_t len)
{
if (dest == NULL || sor == NULL)
{
return NULL;
}
for (int i = 0; i < len; i++)
{
if( (((char*)dest) = ((char*)sor)) == val)
return dest;
}
return dest;
}
//指針法
void * mymemccpybyaddr(void * dest, const void * sor,int val, size_t len)
{
if (dest == NULL || sor == NULL)
{
return NULL;
}
char * pdest = dest;
char * psor = sor;
char * plast = (char *)sor + len;
while (psor < plast)
{
if ((*pdest++ = *psor++) == val)
return dest;
}
return dest;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
char * pstr = (char[50]) { 0 }; //在棧上開辟一段內存
//printf("%s\n", memccpy(pstr,str,'s',32));
printf("%s\n", mymemccpybyaddr(pstr, str, 'f', 32));
system("pause");
}
2.memchr:某段內存中尋找某個值
[C] 純文本查看 復制代碼#include
#include
#include
void * mymemchar(void * buf, int val, size_t size)
{
if (buf == NULL)
{
return NULL;
}
char * p = buf;
char plast = p + size;
while (p < plast)
{
if (*p == val)
{
return p;
}
p++;
}
return NULL;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
printf("%s\n", mymemchar(str, 'g', 8));
system("pause");
}
3.memcpy:拷貝某段內存
[C] 純文本查看 復制代碼#include
#include
#include
//下標法
void * mymemcpybyindex(void * dest, const void * sor, size_t len)
{
if (dest == NULL || sor == NULL)
{
return NULL;
}
for (int i = 0; i < len; i++)
{
((char*)dest) = ((char*)sor);
}
return dest;
}
//指針法
void * mymemcpybyaddr(void * dest, const void * sor, size_t len)
{
if (dest == NULL || sor == NULL)
{
return NULL;
}
char * pdest = dest;
char * psor = sor;
char * plast = (char * )sor + len;
while (psor < plast)
{
*pdest++ = *psor++;
}
return dest;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
char * pstr = (char[50]) { 0 }; //在棧上開辟一段內存
//printf("%s\n", memcpy(pstr, str, 32));
printf("%s\n", mymemcpybyaddr(pstr, str, 31));
system("pause");
}
4.memicmp:比較某段內存大小(一個字節一個字節比較,像strcmp)
注意:切不可用來比較整數,除非一字節整數,因為整數存儲方式是高位高字節
[C] 純文本查看 復制代碼#include
#include
#include
int mymemicmpbyaddr(const void * buf1, const void * buf2, size_t size)
{
char * p1 = buf1;
char * p2 = buf2;
int i = 0;
while(*p1 == *p2 && i < size)
{
p1++;
p2++;
i++;
}
if (*p1 > *p2)
{
return 1;
}
else if (*p1 < *p2)
return -1;
else
return 0;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
char str1[50] = "fengfeng is fucking too handsome";
printf("%d\n", mymemicmpbyaddr(str, str1, 32));
system("pause");
}
5.memmove:和memcpy類似,但是memmove采用了中間空間,memcpy是直接拷貝
兩者區別之處在于當拷貝地址重復的時候,結果不一樣(比較代碼可知)
[C] 純文本查看 復制代碼#include
#include
#include
#include
void * mymemmove(void * dest, const void * sor, size_t size)
{
char * ptemp = malloc(size); //中間 地址
memcpy(ptemp, sor, size);
memcpy(dest, ptemp, size);
free(ptemp);
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
//memmove(str + 3, str + 4, 2);
mymemmove(str + 3, str + 4, 2);
printf("%s\n",str);
system("pause");
}
6.memset:對指定內存每個字節賦某個值
[C] 純文本查看 復制代碼#include
#include
#include
//下標法
void * mymemsetbyindex(void * dest, int val, size_t len)
{
if (dest == NULL)
{
return NULL;
}
if (len == 0)
{
return dest;
}
char * p = dest;
for (int i = 0; i < len; i++)
{
p = val;
}
return dest;
}
//指針法
void * mymemsetbyaddr(void * dest, int val, size_t len)
{
if (dest == NULL)
{
return NULL;
}
if (len == 0)
{
return dest;
}
char * p = dest;
char * plast = p + len;
while (p < plast)
{
*p++ = val;
}
return dest;
}
void main()
{
char str[50] = "fengcong is fucking too handsome";
//printf("%s\n", memset(str, 65, 8));
printf("%s\n", mymemsetbyaddr(str, 65, 8));
system("pause");
}
*******結束語*******
內容應該都不難,希望大家討論討論,認真實現,不要讓這基本功成為
面試官揮動大斧砍你工資的把柄
文中代碼區,少許地方少*,不知道為什么,請注意添加
再會了,還是那句話,你們開心就好,拜個早年!
= ̄ω ̄=
總結
以上是生活随笔為你收集整理的字符串转内存c语言,【一起学C】C语言面试题必考:字符串操作函数,内存操作函数实现...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git@github.com:Permi
- 下一篇: 西安理工大学计算机研究生名单,西安理工大