1. 程式人生 > >mem系列函式(memset memcpy memmove) 和str系列函式(strlen strcpy strcmp strcat strstr strtok)

mem系列函式(memset memcpy memmove) 和str系列函式(strlen strcpy strcmp strcat strstr strtok)

 void *memset(void *s, int ch, size_t n);
 函式解釋:將s中前n個位元組 (typedef unsigned int size_t )用 ch 替換並返回 s 。
 memset:作用是在一段記憶體塊中填充某個給定的值,它是對較大的結構體或陣列進行清零操作的一種最快方法
 最常見的錯誤:memset是按位元組填充的,對其他多餘一個位元組的型別填充要注意


************************************************************
 
  void *memcpy(void *dest, const void *src, size_t n);
  1.source和destin所指的記憶體區域可能重疊,但是如果source和destin所指的記憶體區域重疊,
  那麼這個函式並不能夠確保source所在重疊區域在拷貝之前不被覆蓋。而使用memmove可以用來處理重疊區域。函式返回指向destin的指標.
  2.如果目標陣列destin本身已有資料,執行memcpy()後,將覆蓋原有資料(最多覆蓋n)。如果要追加資料,則每次執行memcpy後,
  要將目標陣列地址增加到你要追加資料的地址。
  注意:source和destin都不一定是陣列,任意的可讀寫的空間均可。
void* memcpy(void*dest,constvoid*src,size_tcount)
{
    assert(dest!=NULL && src!=NULL);
    char* tmp=dest;
    const char* s=src;
    for(size_t i=0;i<count;i++)
{
    tmp[i]=s[i];
}
    return dest;
}


************************************************************
 
  原型:void *memmove( void* dest, const void* src, size_t count );
  標頭檔案:<string.h>
  功能:由src所指記憶體區域複製count個位元組到dest所指記憶體區域。
  相關函式:memset、memcpy
  memmove用於從src拷貝count個字元到dest,如果目標區域和源區域有重疊的話,memmove能夠保證源串在被覆蓋之前

  將重疊區域的位元組拷貝到目標區域中。但複製後src內容會被更改。但是當目標區域與源區域沒有重疊則和memcpy函式功能相同。

*******************************************************

extern unsigned int strlen(char *s);
 strlen(char*)函式求的是字串的實際長度,它求得方法是從開始到遇到第一個'\0',如果你只定義沒有給它賦初值,
 這個結果是不定的,它會從aa首地址一直找下去,直到遇到'\0'停止。

而sizeof()返回的是變數聲明後所佔的記憶體數,不是實際長度,此外sizeof不是函式,僅僅是一個取位元組運算子,strlen是函式。

********************************************************

原型宣告:char *strcpy(char* dest, const char *src);
標頭檔案:#include <string.h> 和 #include <stdio.h>
功能:把從src地址開始且含有NULL結束符的字串複製到以dest開始的地址空間
說明:src和dest所指記憶體區域不可以重疊且dest必須有足夠的空間來容納src的字串。
返回指向dest的指標。

為什麼返回 char* 型別的dest指標?

(A)return new string("Invalid argument(s)");,說明答題者根本不知道返回值的用途,並且他對記憶體洩漏也沒有警惕心。
從函式中返回函式體內分配的記憶體是十分危險的做法,他把釋放記憶體的義務拋給不知情的呼叫者,絕大多數情況下,呼叫者不會釋放記憶體,
這導致記憶體洩漏。
(B)return 0;,說明答題者沒有掌握異常機制。呼叫者有可能忘記檢查返回值,呼叫者還可能無法檢查返回值(見後面的鏈式表示式)。
妄想讓返回值肩負返回正確值和異常值的雙重功能,其結果往往是兩種功能都失效。應該以丟擲異常來代替返回值,這樣可以減輕呼叫者的負擔、
使錯誤不會被忽略、增強程式的可維護性。
[3]
(A)忘記儲存原始的strDest值,說明答題者邏輯思維不嚴密。
[4]
(A)迴圈寫成while (*strDestCopy++=*strSrc++);,同[1](B)。
(B)迴圈寫成while (*strSrc!='\0') *strDest++=*strSrc++;,說明答題者對邊界條件的檢查不力。迴圈體結束後,strDest字串的末尾沒有正確地加上'\0'。
⒉返回strDest的原始值使函式能夠支援鏈式表示式,增加了函式的“附加值”。同樣功能的函式,如果能合理地提高的可用性,自然就更加理想。

******************************************************************

extern int strcmp(const char *s1,const char *s2);

規則
當s1<s2時,返回為負數
當s1=s2時,返回值= 0
當s1>s2時,返回正數
即:兩個字串自左向右逐個字元相比(按ASCII值大小相比較),直到出現不同的字元或遇'\0'為止。如:
"A"<"B" "a">"A" "computer">"compare"
特別注意:strcmp(const char *s1,const char * s2)這裡面只能比較字串,即可用於比較兩個字串常量,或比較陣列和字串常量,不能比較數字等其他形式的引數。

int strcmp(const char *str1,const char *str2)
{
    /*不可用while(*str1++==*str2++)來比較,當不相等時仍會執行一次++,
    return返回的比較值實際上是下一個字元。應將++放到迴圈體中進行。*/
    while(*str1 == *str2)
    {
        if(*str1 == '\0')
            return0;
         
        str1++;
        str2++;
    }
    return *str1 - *str2;
}

***************************************************************************


extern char *strcat(char *dest,char *src);
用法

#include <string.h>
在C++中,則存在於<cstring>標頭檔案中。
功能

把src所指字串新增到dest結尾處(覆蓋dest結尾處的'\0')並新增'\0'。
說明

src和dest所指記憶體區域不可以重疊且dest必須有足夠的空間來容納src的字串。
返回指向dest的指標。

 char *mystrcat(char *dst,const char *src) //用自己的方式實現strcat函式功能
   {
       char *p=dst;  //下面的操作會改變目的指標指向,先定義一個指標記錄dst
       while(*dst!='\0')dst++;
       while(*src!='\0')*dst++=*src++;
       *dst='\0';
       return p;  //dst現在指向拼接後的最後一位字元,在這裡返回dst,會出現錯誤
    }

*******************************************************************************

函式原型:
extern char *strstr(char *str1, const char *str2);
語法:
* strstr(str1,str2)
str1: 被查詢目標 string expression to search.
str2: 要查詢物件 The string expression to find.
返回值:若str2是str1的子串,則返回str2在str1的首次出現的地址;如果str2不是str1的子串,則返回NULL。

char *strstr(const char*s1,const char*s2)
{
    const char*p=s1;
    const size_tlen=strlen(s2);
    for(;(p=strchr(p,*s2))!=0;p++)
    {
        if(strncmp(p,s2,len)==0)
            return (char*)p;
    }
    return(0);
}
*****************************************************************************

char *strtok(char s[], const char *delim);

分解字串為一組字串。s為要分解的字串,delim為分隔符字串。
例如:strtok("abc,def,ghi",","),最後可以分割成為abc def ghi.尤其在點分十進位制的IP中提取應用較多。

strtok()用來將字串分割成一個個片段。引數s指向欲分割的字串,引數delim則為分割字串中包含的所有字元。當strtok()在引數s的字串中發現引數delim中包含的分割字元時,則會將該字元改為\0 字元。在第一次呼叫時,strtok()必需給予引數s字串,往後的呼叫則將引數s設定成NULL。每次呼叫成功則返回指向被分割出片段的指標。

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    char sentence[]="This is a sentence with 7 tokens";
    cout << "The string to be tokenized is:\n" << sentence << "\n\nThe tokens are:\n\n";
    char *tokenPtr=strtok(sentence,"");
    while(tokenPtr!=NULL) {
        cout<<tokenPtr<<'\n';
        tokenPtr=strtok(NULL,"");
    }
    //cout << "After strtok,sentence=" << tokenPtr<<endl;
    return 0;
}



相關推薦

mem系列函式(memset memcpy memmove) str系列函式(strlen strcpy strcmp strcat strstr strtok)

 void *memset(void *s, int ch, size_t n);  函式解釋:將s中前n個位元組 (typedef unsigned int size_t )用 ch 替換並返回 s 。  memset:作用是在一段記憶體塊中填充某個給定的值,它是對較大的

memcpy,memmove,bcopy三個函式的記憶體重疊

bcopy correctly handles overlapping fields, while the behavior of memcpy is undefined if the source and destination overlap. The ANSI C me

Scala學習筆記(六):本地函式、頭等函式、佔位符部分應用函式

本地函式 可以在方法內定義方法,這種方法叫本地函式,本地函式可以直接訪問父函式的引數 def parent(x: Int, y: Int): Unit ={ def child(y:Int) = y + 1 val z = child(y) println(s"x: $x, z

高斯分佈概率密度函式(PDF)累積分佈函式(CDF)

正態分佈(Normal distribution)又名高斯分佈(Gaussian distribution),是一個在數學、物理及工程等領域都非常重要的概率分佈,在統計學的許多方面有著重大的影響力。 若隨機變數X服從一個數學期望為μ、標準方差為σ2的高斯分佈,記為:X∼

一個案例講解獲取字串長度的函式mb_strlen()字串擷取函式mb_substr()

這是在專案中遇到的一小段,包含了mb_strlen()和mb_substr()兩個函式: > function _cut($_string,$_strlen){ > if(mb_

類成員函式轉換成void (*)靜態成員函式獲取非靜態成員變數的方法

很多第三方函式需要把函式轉換成void(*)型別,如libevent 1.4版本中的event_set函式: 如果要傳遞類成員函式給相應的函式我們應該怎樣處理呢? 僅僅傳遞類成員函式可以嗎? 不可以的!編譯的時候會遇到下面的錯誤: cannot convert DataWa

編寫一個矩形rectangle類,有資料成員長len寬wid,建構函式retange(int,int).友元函式 int area(rectangle T)int fun(rectangle T

#include <iostream> using namespace std; class rectangle { public: rectangle(int ,int ); friend int area(rectangle T); friend

mem家族(memsetmemcpy)

1. mem開頭的函式基本上都是對記憶體操作的,     它們不管記憶體裡放的是什麼資料,只要給出長度,它們就操作。不像strcpy、strcmp等函式一定以'\0'結尾,而且是字元。mem可以操作可見字元、不可見字元、控制字元等,任意資料都可以。 2. memcpy是記憶

memset memcmp memcpy memmove 自己實現

assert for source null 方式 size_t res 取值 從後往前 memset memcmp memcpy memmove 自己實現 memset #include <stdio.h> #include <memory.h>

memmovememcpy的區別

memcpy和memmove都是C語言的庫函式,在標頭檔案string.h中,作用是記憶體拷貝,原型如下“ 它們的作用都是記憶體拷貝,唯一的區別是,當記憶體發生區域性重疊時,memmove保證了拷貝的結果是正確的,但是memcopy不一定是正確的。但是memcpy比memmove速度快

本地系統服務例程:NtZw系列函式

Windows本地作業系統服務API由一系列以Nt或Zw為字首的函式實現的,這些函式以核心模式執行,核心驅動可以直接呼叫這些函式,而使用者層程式只能通過系統進行呼叫。通常情況下使用者層應用程式不會直接呼叫Nt和Zw系函式,更多的是通過直接呼叫Win32函式,這些Win32函式內部會呼叫Nt和Zw系函式,但也僅

深度學習基礎系列(五)| 深入理解交叉熵函式及其在tensorflowkeras中的實現

  在統計學中,損失函式是一種衡量損失和錯誤(這種損失與“錯誤地”估計有關,如費用或者裝置的損失)程度的函式。假設某樣本的實際輸出為a,而預計的輸出為y,則y與a之間存在偏差,深度學習的目的即是通過不斷地訓練迭代,使得a越來越接近y,即 a - y →0,而訓練的本質就是尋找損失函式最小值的過程。   常見的

python 中的%s%r、str.format()函式

%r是repr %s就是str >>> print '%r' % 'a' 'a' >>> print '%s' % 'a' a >>> class

memmovememcpy

1.memmove 函式原型:void *memmove(void *dest, const void *source, size_t count) 返回值說明:返回指向dest的void *指標 引數說明:dest,source分別為目標串和源串的首地址。count為要移動的字元的個數 函式說明:memm

面試必問系列之 建構函式,原型物件例項之間的關係(一)

關於建構函式,原型物件,例項之間的關係  ,先來看一張圖,大致瞭解下1,建構函式建構函式跟普通函式沒什麼區別,都是由function定義的,為了和普通函式做區別,一般建構函式首字母大寫像這樣,建構函式可以使用new操作符呼叫,也可以像普通函式那樣呼叫,如果像普通函式那樣呼叫,

memcpy memmove區別實現(如何處理記憶體重疊問題)

memcpy與memmove的目的都是將N個位元組的源記憶體地址的內容拷貝到目標記憶體地址中。 但當源記憶體和目標記憶體存在重疊時,memcpy會出現錯誤,而memmove能正確地實施拷貝,但這也增加了一點點開銷。 memmove的處理措施: (1)當源記憶體的首地址等於目標記憶體的首地址時,不進行任何拷貝

[c語言]對各種字串庫函式的實現strcpy,strcat,strstr,strchr,strcmp,memcpy,memmove

1.模擬實現strcpy //1.模擬實現strcpy(字串拷貝) #include<stdio.h> #include<assert.h> char * my_strcpy(char *dest,const char *str) {

TTCN3新執行器系列-如何最小化類的成員函式(對拷貝構造賦值操作函式的反思)

2009年4月份,我們的TTCN3新執行器大體功能已經完成了,於是找了幾個專案來試點應用。 應用效果不太理想,特別是對於5萬行以上的指令碼工程,且包括大asn檔案的情況。 新執行器轉換出來的C++程式碼量很大,特別是由於asn型別很多,導致hpp檔案程式碼量大的編譯速度下降嚴

python datetimestr轉換 計算時間差;Python 函式接收元組字典引數

server上跑housecleaning的指令碼,需要比較時間內容 例如t1 和t2都是datetime.datetime型別,則可以通過下面的sample code來計算二者的時間差 def __time_diff(t1,t2): seconds = (t1

《笨辦法學 python3》系列練習計劃——35.分支函式

題目 我們已經學會了 if 語句、函式還有列表。現在我們需要搞清楚本題程式碼實現的是什麼功能。 加分練習 把這個遊戲的地圖畫出來,把自己的路線也畫出來。 改正你所有的錯誤,包括拼寫錯誤。 為不懂的地方寫註解。 為遊戲新增更多元素。通過怎樣得方式可以簡