91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用c語言字符串操作函數

發布時間:2021-10-15 13:38:24 來源:億速云 閱讀:133 作者:iii 欄目:開發技術

本篇內容介紹了“如何使用c語言字符串操作函數”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一,常量指針與指針常量

先來補充一個上篇文章 手把手教你深入理解c/c++中的指針 我在講述指針中的一個問題,有人說常量指針與指針常量這兩個概念總是混淆怎么辦,例如:

int a = 100;
const int * p = &a;  //常量指針,指向的值不可更改,但指向的地址可以更改
int const * p = &a;  //與上式等價
int * const p = &a;  //指針常量,指向的地址不可以更改,但指向的值可更改

那么究竟如何區分常量指針與指針常量呢,這里邊有個技巧,上篇文章中我忘記給大家說了:

從左往右看,跳過類型,看修飾哪個字符,如果是*, 說明指針指向的值不能改變,如果是指針變量,說明指針的指向不能改變,指針的值不能修改。這個原則你可以通俗理解成 “就近原則”。

那么回頭來看第一行代碼,也就是指針常量:

const int * p = &a;

我們跳過變量類型 int ,那么const修飾的是*,所以它指向的值不能修改

第二行代碼,常量指針:

int * const p = &a;

同樣,我們跳過int,發現const是直接修飾的p,所以它的指向不能改變。兩者有細微的差別,請大家注意。

我們再回到本節的字符串問題上,在講述字符串拷貝函數前,我們再來回憶一下c語言中的字符串。

我們知道,c語言中的字符串有兩種定義的方法,分別是:

char str1[] = "hello world";  //棧區字符串
char* str2 = "hello world";  //數據常量區字符串

那么這兩種在使用起來究竟有什么區別呢?答案是第一行定以后,操作系統給它分配的是棧區內存,而第二行通過指針形式來定義字符串的話,它分配的內存區在數據的常量區,意味著它的值是不可更改的:

str1[0] = 'm';  //正確,字符數組可以修改
str2[0] = 'm';  //錯誤,常量區不可修改

所以,在常量區,如果我們兩個內容相同但變量不同的指針變量,其實它們指向的是同一塊內存:

char* str1 = "hello world";  
char* str2 = "hello world";  
printf("%p\n",str1);
printf("%p\n",str2);

上面兩行代碼中,我們將str1與str2指向的內存地址分別打印出來,發現他們的值是一樣的,為什么呢,這是因為常量區內存的值是只讀的,我們即便聲明兩個不同的變量,只要他們的值是相同的,那么兩個變量指向的就是同一塊內存區域。

這里值得注意的是,在c++中,字符串指針與c語言中稍有區別,c++中直接將字符串指針做了增強處理,因為c++中規定字符串指針必須用const修飾,例如在c++中這樣定義,編譯器會直接報錯:

char* str = "hello world";  //直接報錯
const char * str = "hello world";  //正確

而在實際開發過程中,我們使用字符串一般使用數組形式,不太建議使用指針字符串形式,也即:

char str[] = "hello world";  //建議使用
char* str = "hello world";  //不建議使用

所以,這方面細微的差別請大家注意。

二,字符串長度問題

我們知道c語言中的字符串是以 '\0' 為結尾的,也就是說你在聲明一個字符串的時候,系統會自動為你的結尾添加上一個以 '\0' 為結尾的結束字符,而且,printf 在每打印一個字符就會檢查當前字符是否為 ‘\0' ,直到遇到 '\0' 立馬停止。這里最容易混淆的的是字符串的長度,我們來看下面兩行代碼:

我們先來看下面兩行代碼:

char str1[] = "hello";
char* str2 = "hello";
printf("%d\n", sizeof(str1));  //輸出結果為 6
printf("%d\n", sizeof(str2));  //輸出結果為 4 或者 8

那么為什么在使用 sizeof 計算字符串長度,兩者計算出來的結果不一樣呢,而且第一行長度還不是我們想要的,不應該是 5 才對嗎?這是因為在聲明一個字符串的時候,系統會自動為你的結尾添加上一個以 '\0' 為結尾的結束字符,內存模型如下:

如何使用c語言字符串操作函數

所以,對于上面兩行代碼,實際上它們的長度都為 6 才對。那為什么第二行輸出卻為 4 呢,這是因為第二行我們定義的是一個字符串指針,它指向一個常量區的字符串,而 sizeof 操作符操作這個指針的時候,實際上計算的是這個指針的字節長度,而一個指針在x86系統下占有長度為 4 字節,在x64環境下占有長度為 8 字節,所以,在實際上我們計算字符串長度的時候,一般會用 strlen() 這個函數,但是要注意,strlen 計算字符串也是以 '\0' 為結束的,也就是說,strlen() 函數會不斷判斷當前字符是否為 '\0',如果是的話,立馬結束,這個特點與printf函數一樣,兩者都是碰到 '\0' 就立馬結束:

char str1[] = "abc";
char str2[] =  {'a', '\0', 'c'};
char str3[] =  {'a', 'b', 'c', '\0'};
char* str4 = "abc";
printf("%d\n", strlen(str1));  //輸出結果為 3
printf("%d\n", strlen(str2));  //輸出結果為 1
printf("%d\n", strlen(str3));  //輸出結果為 3
printf("%d\n", strlen(str4));  //輸出結果為 3

上面就是c語言中的字符串長度函數,在使用過程中千萬要注意。

三,c語言中的字符串拷貝函數

1) strcpy()

#include <string.h>
char *strcpy(char *dest, const char *src);
//功能:把src所指向的字符串復制到dest所指向的空間中,'\0'也會拷貝過去
參數:
  dest:目的字符串首地址
  src:源字符首地
返回值:
  成功:返回dest字符串的首地址
  失敗:NULL

示意代碼如下:

  #define _CRT_SECURE_NO_WARNINGS
  #include <string.h>
  char str[10] = { 0 };
  char str1[] = "hello";
  char* mystr = strcpy(str, str1);  將strcpy返回的指針保存到mystr里面
  printf(mystr);

內存模型如下:

如何使用c語言字符串操作函數

由于是逐個拷貝,意味著哪怕在字符串的中間遇到了 '\0' 字符,也會結束拷貝。

這里邊要注意兩個問題:第一,必須保證 dest 所指向的內存空間足夠大,否則可能會造成緩沖溢出的錯誤;第二,由于本身strcpy函數是一個非安全函數,所以編譯器會彈出警告,要想忽略,請在程序最開頭添加宏定義代碼:

#define _CRT_SECURE_NO_WARNINGS

2), strncpy()

#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
功能:
  把src指向字符串的前n個字符復制到dest所指向的空間中,
  是否拷貝結束符看指定的長度是否包含'\0'。
參數:
  dest:目的字符串首地址
  src:源字符首地址
  n:指定需要拷貝字符串個數
返回值:
  成功:返回dest字符串的首地址
  失敗:NULL

這個函數與strcpy類似,這里不再累贅。

3), strcat()

#include <string.h>
char *strcat(char *dest, const char *src);
功能:將src字符串連接到dest的尾部,‘\0'也會追加過去
參數:
  dest:目的字符串首地址
  src:源字符首地址
返回值:
  成功:返回dest字符串的首地址
  失敗:NULL

這是一個字符串追加函數,將 src 指向的字符串追加到 dest 指向的字符串后面,同樣,結束符 '\0' 也會追加過去:

  #define _CRT_SECURE_NO_WARNINGS
  #include <string.h>
  char str[] = "123";
  char str1[] = "hello";
  char* mystr = strcat(str, str1);
  printf("%s\n%p", mystr, mystr);  
  //輸出結果為:123hello

但是同樣注意的是,目標字符串 dest 要有足夠大的緩沖區來接收,否則會報錯,內存模型如下:

如何使用c語言字符串操作函數

4), strncat()

#include <string.h>
char *strncat(char *dest, const char *src, size_t n);
功能:將src字符串前n個字符連接到dest的尾部,‘\0'也會追加過去
參數:
  dest:目的字符串首地址
  src:源字符首地址
  n:指定需要追加字符串個數
返回值:
  成功:返回dest字符串的首地址
  失敗:NULL

這個函數與strcat類似,只不過指定了追加的數量。

5), strcmp()

#include <string.h>
char *strcat(char *dest, const char *src);
功能:將src字符串連接到dest的尾部,‘\0'也會追加過去
參數:
  dest:目的字符串首地址
  src:源字符首地址
返回值:
  成功:返回dest字符串的首地址
  失敗:NULL

作用是對兩個字符串的ASCII碼進行比較,輸出不同結果,經常用于判斷兩個字符串是否相等,示例代碼如下:

char *str1 = "hello world";
char *str2 = "hello mike";

if (strcmp(str1, str2) == 0)
{
  printf("str1==str2\n");
}
else if (strcmp(str1, str2) > 0)
{
  printf("str1>str2\n");
}  
else
{
  printf("str1<str2\n");
}

6), strncmp()

#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
功能:比較 s1 和 s2 前n個字符的大小,比較的是字符ASCII碼大小。
參數:
  s1:字符串1首地址
  s2:字符串2首地址
  n:指定比較字符串的數量
返回值:
  相等:0
  大于:> 0
  小于: < 0

這個函數作用也是與strcmp類似,不再累贅。

7), sprintf()

#include <stdio.h>
int sprintf(char *str, const char *format, ...);
功能:根據參數format字符串來轉換并格式化數據,
      然后將結果輸出到str指定的空間中,
      直到出現字符串結束符 '\0' 為止。
參數:
  str:字符串首地址
  format:字符串格式,用法和printf()一樣
返回值:
  成功:實際格式化的字符個數
  失敗: - 1

示例代碼如下:

  char dst[100] = { 0 };
  int a = 10;
  char src[] = "hello";
  int len = sprintf(dst, "a=%d, src=%s", a, src);
  printf("dst: %s\n", dst);  輸出 a=10,src=hello
  printf("len = %d\n", len);  輸出14

下面再介紹幾個字符串操作函數,但這幾個使用頻率比較小:

8) sscanf()

#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
功能:從str指定的字符串讀取數據,
  并根據參數format字符串來轉換并格式化數據。
參數:
  str:指定的字符串首地址
  format:字符串格式,用法和scanf()一樣
返回值:
  成功:參數數目,成功轉換的值的個數
  失敗: - 1

示例代碼:

  char src[] = "a=10, b=20";
  int a;
  int b;
  sscanf(src, "a=%d,  b=%d", &a, &b);
  printf("a:%d, b:%d\n", a, b);
  輸出:a:20,b:20

sscanf與scanf類似,都是用于輸入的,只是后者以屏幕(stdin)為輸入源,前者以固定字符串為輸入源。

9) strchr()

#include <string.h>
char *strchr(const char *s, char c);
功能:在字符串s中查找字母c出現的位置
參數:
  s:字符串首地址
  c:匹配字母(字符)
返回值:
  成功:返回第一次出現的c地址(注意是地址,不是字符數組索引)
  失敗:NULL

示例代碼:

char src[] = "ddda123abcd";
char *p = strchr(src, 'a');
printf("p = %s\n", p);
輸出:p=a123abcd

10), strstr()

#include <string.h>
char *strstr(const char *haystack, const char *needle);
功能:在字符串haystack中查找字符串needle出現的位置
參數:
  haystack:源字符串首地址
  needle:匹配字符串首地址
返回值:
  成功:返回第一次出現的needle地址
  失敗:NULL

這個函數與上一個 strchr 功能類似,只不過查找的內容是字符串,而非字單個字符。

11) strtok()

#include <string.h>
char *strtok(char *str, const char *delim);
功能:將字符串分割成一個個片段, 
      當strtok()在參數str的字符串中發現參數delim中包含的分割字符時, 
      則會將該字符改為\0 字符,當連續出現多個時只替換第一個為\0,
      該函數會破壞原有字符串。
參數:
  str:指向欲分割的字符串
  delim:為分割字符串中包含的所有字符
返回值:
  成功:分割后字符串首地址
  失敗:NULL

示例代碼:

char a[100] = "www.baidu.com";
char *p = strtok(a, ".");
while (p != NULL)
{  
  printf("%s\n", p);  
  p = strtok(NULL, ".");
}
輸出:www baidu com

“如何使用c語言字符串操作函數”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

满洲里市| 新田县| 叙永县| 米易县| 新化县| 万安县| 黎城县| 平果县| 蒙城县| 荔波县| 宣化县| 娄底市| 宝山区| 重庆市| 琼中| 布尔津县| 彰武县| 洛阳市| 望江县| 莒南县| 资源县| 淮北市| 五大连池市| 海淀区| 玉树县| 太康县| 孝昌县| 丰宁| 定安县| 新建县| 青浦区| 昌宁县| 栖霞市| 噶尔县| 新干县| 长治县| 义马市| 萨迦县| 白城市| 临沧市| 彩票|