小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

實現(xiàn)一些字符串操作標準庫函數(shù)、解決一些字符串問題的總結(jié)

 C語言與CPP編程 2022-10-08 發(fā)布于安徽

首先推薦下最近給大家總結(jié)的一些學習網(wǎng)站

神級編程網(wǎng)站,堪稱程序員的充電站,我給你找好了不能錯過_程序員編程指南的博客-CSDN博客

1、實現(xiàn)字符串操作標準庫函數(shù)

1、strcpy 的實現(xiàn)

char?*strcpy(char?*dest,?const?char?*src)
{
????assert((src?!=?NULL)?&&?(dest?!=?NULL));
????size_t?i;
????for?(i?=?0;?src[i]?!=?'\0';?i++)
????????dest[i]?=?src[i];
????dest[i]?=?'\0';
????return?dest;
}

2、strncpy 的實現(xiàn)

char?*strncpy(char?*dest,?const?char?*src,?size_t?n)
{
????assert((src?!=?NULL)?&&?(dest?!=?NULL));
????size_t?i;
????for?(i?=?0;?i?<?n?&&?src[i]?!=?'\0';?i++)
????????dest[i]?=?src[i];
????for?(;?i?<?n;?i++)
????????dest[i]?=?'\0';
????return?dest;
}

3、memmove 的實現(xiàn)

/*?借助于一個臨時緩沖區(qū)temp?,即使src?和dest?所指的內(nèi)存區(qū)間有重疊也能正確拷貝。*/
void?*memmove(void?*dest,?const?void?*src,?size_t?n)
{
????assert((src?!=?NULL)?&&?(dest?!=?NULL));
????char*?temp?=?(char*)malloc(sizeof(char)*n);
????size_t?i;
????char?*d?=?(char*)dest;
????const?char?*s?=?(const?char*)src;

????for?(i?=?0;?i?<?n;?i++)
????????temp[i]?=?s[i];
????for?(i?=?0;?i?<?n;?i++)
????????d[i]?=?temp[i];

????free(temp);
????
????return?dest;
}

不用臨時空間的memmove實現(xiàn):

//src可以不保留
void?*memmove(void?*dst,?const?void?*src,?size_t?count)
{
????byte?*pbTo?=?(byte?*)dst;
????byte?*pbFrom?=?(byte?*)src;
????assert(dst?!=?NULL?&&?src?!=?NULL);//不能存在空指針
????if?(dst?<=?src?||?pbTo?>=?pbFrom?+?count)//
????{
????????while?(count--?>?0)
????????{
????????????*pbTo++?=?*pbFrom++;?//按遞增拷貝
????????}
????}
????else??//
????{
????????pbTo?=?pbTo?+?count?-?1;?//overlap的情況,從高位地址向低位拷貝
????????pbFrom?=?pbFrom?+?count?-?1;
????????while?(count--?>?0)
????????{
????????????*pbTo--?=?*pbFrom--;?//按遞減拷貝
????????}
????}
????return?dst;
}

4、memcpy 的實現(xiàn)

/*?在32位的x86平臺上,每次拷貝1個字節(jié)需要一條指令,每次拷貝4個字節(jié)也只需要一條指
?*?令,memcpy函數(shù)的實現(xiàn)盡可能4個字節(jié)4個字節(jié)地拷貝?*/
void?*memcpy(void?*dest,?const?void?*src,?size_t?n)
{
????assert((src?!=?NULL)?&&?(dest?!=?NULL));
????char?*d?=?dest;
????const?char?*s?=?src;
????int?*di;
????const?int?*si;
????int?r?=?n?%?4;
????while?(r--)
????????*d++?=?*s++;
????di?=?(int?*)d;
????si?=?(const?int?*)s;
????n?/=?4;
????while?(n--)
????????*di++?=?*si++;
????return?dest;
}

5、strlen 的實現(xiàn)

size_t?strlen(const?char?*p)
{
????assert(p?!=??NULL);
????size_t?size?=?0;
????while?(*p++?!=?'\0')
????????++size;
????return?size;
}

6、strncat 的實現(xiàn)

char?*strncat(char?*dest,?const?char?*src,?size_t?n)
{
????size_t?dest_len?=?strlen(dest);
????size_t?i;

????for?(i?=?0?;?i?<?n?&&?src[i]?!=?'\0'?;?i++)
????????dest[dest_len?+?i]?=?src[i];
????dest[dest_len?+?i]?=?'\0';

????return?dest;
}

7、memset 的實現(xiàn)

void?*memset(void?*buffer,?int?c,?int?count)
{
????char?*buffer_p?=?(char?*)buffer;
????assert(buffer?!=?NULL);
????while(count--?>?0)
????????*buffer_p++?=?(char)c;
????return?buffer;
}

2、解決字符串問題

1、將單詞之間出現(xiàn)一個或多個連續(xù)的空白字符都壓縮為1個

//編一個函數(shù),輸入一個字符串,要求做一個新字符串,把其中所有的一個或多個連續(xù)的空白字符都壓縮為一個空格。這里所說的空白包括空格、'\t'、'\n'、'\r'。
char?*shrink_space(char?*dest,?const?char?*src,?size_t?n)
{
????assert((src?!=?NULL)?&&?(dest?!=?NULL));
????size_t?i,?j;

????dest[0]?=?src[0];

????for?(i?=?1,?j?=?1;?src[i]?!=?'\0';?i++,?j++)
????{
????????if?(src[i]?==?'\t'?||?src[i]?==?'\n'
????????????????||?src[i]?==?'\r'?||?src[i]?==?'?')

????????????if?(src[i?-?1]?!=?'\t'?&&?src[i?-?1]?!=?'\n'
????????????????????&&?src[i?-?1]?!=?'\r'?&&?src[i?-?1]?!=?'?')

????????????????dest[j]?=?'?';
????????????else
????????????????j--;
????????else
????????????dest[j]?=?src[i];
????}
????dest[j]?=?'\0';

????return?dest;
}

2、解析URL 中的路徑和查詢字符串。? 號后面是查詢字符串,由 “key=value”形式的鍵值對組成,以&隔開

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define?N?10
typedef?struct
{
????char?*tokens[N];
????int?count;
}?unit_t;

void?find_url_token(char?str[],?const?char?tok[],?unit_t?*ptr)
{
????int?i;
????char?*token?=?NULL;
????char?*saveptr?=?NULL;

????ptr->count?=?0;
????const?char?*needle?=?"://";

????if?(strstr(str,?needle))
????{
????????for?(i?=?0;?;?str?=?NULL,?i++)
????????{
????????????token?=?strtok_r(str,?tok,?&saveptr);
????????????if?(token?==?NULL)
????????????????break;
????????????else
????????????{
????????????????ptr->tokens[i]?=?token;
????????????????ptr->count++;
????????????}
????????}
????}
}

int?main(void)
{
????/*?不能定義為char?*url?=?"...";?因為此時是定義一個指向字符串字面值(位于.rodata段)的指針,而
???????調(diào)用strtok_r函數(shù)會修改這個字符串,運行時會產(chǎn)生段錯誤?*/
????char?url[]?=?"http://www.google.cn/search?complete=1&hl=zh-CN&ie=GB2312&q=linux&meta=";
????/*?給url初始化用的這個字符串并沒有分配在.rodata段,而是直接寫在指令里了,
?????*?運行程序時通過movl?指令把字符串寫到棧上,這就是url的存儲空間*/
????unit_t?*ptr?=?malloc(sizeof(unit_t));
????find_url_token(url,?"?&",?ptr);
????int?i;
????for?(i?=?0;?i?<?ptr->count;?i++)
????????printf("%s\n",?ptr->tokens[i]);
????free(ptr);
????return?0;
}

3、去除\r\n,去除左右空白字符

void?str_trim_crlf(char?*str)
{
????char?*p?=?&str[strlen(str)?-?1];
????while?(*p?==?'\r'?||?*p?==?'\n')
????????*p--?=?'\0';
}
void?AllTrim(?char?*str?)
{
????char?*head,?*tail;

????if?(?str?==?NULL?)
????????return;

????for(?head?=?str;?*head?==?'?'?||?*head?==?'\t';?head?++?);

????for(?tail?=?str?+?strlen(str)?-?1;?(*tail?==?'?'?||?*tail?==?'\t'?)?&&?tail?>=?head;?tail?--?);

????while(?head?<=?tail?)
????????*str?++?=?*head?++;

????*str?=?0;
}

4、判斷字符串是否為回文

//?判斷字符串是否為回文
bool?isSysmmetry(const?char?*src)
{
????assert(src?!=?NULL);
????int?len?=?strlen(src);
????assert(len?!=?0);
????const?char?*tmp?=?src?+?len?-?1;

????int?i;
????for?(i?=?0;?i?<?len?/?2;?i++)
????{
????????if?(*src++?!=?*tmp--)
????????????break;
????}

????if?(i?==?len?/?2)
????????return?true;
????else
????????return?false;

}

5、google筆試:編碼實現(xiàn)求給定字符串(全為小寫英文字母)的最小后繼,如 “abc” 的最小后繼為“abd”, "dhz" 的最小后繼為“di"

int?MinNextStr(const?char?*src,?char?*&minnext)
{
????int?srclen?=?strlen(src);
????minnext?=?(char?*)malloc((srclen?+?1)?*?sizeof(char));
????if?(minnext?==?NULL)
????????return?-1;
????strcpy(minnext,?src);

????int?i?=?srclen?-?1;
????while?(i?>=?0)
????{
????????minnext[i]++;
????????if?(minnext[i]?<=?'z')
????????????break;
????????i--;
????}

????if?(i?<?0)
????????return?0;
????else
????{
????????minnext[++i]?=?'\0';
????????return?1;

????}
}

如果把給定字符串全為小寫英文字母改為大小寫英文字母,則只要把 第 13 行改為: if (minnext[i] <= 'z' && minnext[i] >= 'a' || minnext[i] <= 'Z');

6、中興:編碼實現(xiàn)字符串右移n位,如“diopheg” 右移2位為“egdioph”。

bool?RightMoveStr(char?*src,?int?n)
{
????int?len?=?strlen(src);
????int?mov?=?n?%?len;
????char?*rstr?=?(char?*)malloc((mov?+?1)?*?sizeof(char));
????if?(rstr?==?NULL)
????????return?false;

????int?i?=?0;
????while?(i?<?mov)
????{
????????rstr[i]?=?src[len?-?mov?+?i];
????????i++;
????}
????rstr[i]?=?'\0';

????i?=?len?-?mov?-?1;
????while?(i?>=?0)
????{
????????src[i?+?mov]?=?src[i];
????????i--;
????}

????i?=?0;
????while?(i?<?mov)
????{
????????src[i]?=?rstr[i];
????????i++;
????}

????free(rstr);
????return?true;
}

bool?RightMove(char?*src,?char?*&ssrc,?int?n)
{
????int?len?=?strlen(src);
????ssrc?=?(char?*)malloc(sizeof(char)?*?(len?+?1));
????if?(ssrc?==?NULL)
????????return?false;

????n?=?n?%?len;
????char?*tmp?=?src?+?len?-?n;

????strcpy(ssrc,?tmp);
????strncat(ssrc,?src,?len?-?n);

????return?true;

}

更巧妙的方法:

void?reverse(char*?str,?int?left,?int?right)
{
????char?tmp;
????while?(left?<?right)
????{
????????tmp?=?str[left];
????????str[left++]?=?str[right];
????????str[right--]?=?tmp;

????}
}

void?rightmove(char*?str,?int?k)
{
????n?=?strlen(str);
????k?=?k?%?n;
????reverse(str,?0,?n-k-1);
????reverse(str,?n-k,?n-1);
????reverse(str,?0,?n-1);
}

7、新郵通:字符串反轉(zhuǎn):給定字符串“we;tonight;you;”,編碼實現(xiàn)輸出”ew;thginot;uoy;“

void?ReverseStr(char?*src)
{
????int?len?=?strlen(src);
????int?i?=?0;
????int?first?=?0;
????int?end?=?0;
????while?(i?<?len)
????{
????????if?(src[i]?==?';')
????????{
????????????end?=?i?-?1;
????????????while?(first?<?end)
????????????{
????????????????char?tmp?=?src[first];
????????????????src[first]?=?src[end];
????????????????src[end]?=?tmp;
????????????????first++;
????????????????end--;
????????????}
????????????first?=?i?+?1;

????????}
????????i++;
????}
}

如果給定字符串末尾沒有';',只需要修改 9,10,11 行

if?(src[i]?==?';'?||?i?==?len?-?1)
{
????if?(src[i]?==?';')
????????end?=?i?-?1;
????else
????????end?=?i;
????while...
}

8、不使用局部變量實現(xiàn)strlen、兩數(shù)交換

#define?swap(a,b)?{?assert(sizeof(a)==sizeof(b));?char?tempBuf[sizeof(a)];?memcpy(tempBuf,&a,sizeof(a));?memcpy(&a,&b,sizeof(b));?memcpy(&b,tempBuf,sizeof(b));?}

#define?swap(a,?b)?????do?{?typeof(a)?__tmp?=?(a);?(a)?=?(b);?(b)?=?__tmp;?}?while?(0)
//?typeof?是gcc支持,iso?c支持__typeof__
????
???
int?mstrlen(char?*p)
{
????return?ToEnd(p)-p;
}
char?*?ToEnd(char?*?p)
{
????while(*p?!=?'\0')
????????p++;
????return?p;
}

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多