C語言之字串處理函式

上善若泪發表於2024-06-23

目錄
  • 1 字串處理函式
    • 1.1 輸入輸出
      • 1.1.1 輸出函式puts
      • 1.1.2 輸入函式gets
    • 1.2 連線函式
      • 1.2.1 stract
      • 1.2.2 strncat
    • 1.3 複製
      • 1.3.1 複製strcpy
      • 1.3.2 複製strncpy
      • 1.3.3 複製memcpy
      • 1.3.4 指定複製memmove
      • 1.3.5 指定複製memset
      • 1.3.6 新建複製strdup
      • 1.3.7 字串設定strset
    • 1.4 比較
      • 1.4.1 比較strcmp
      • 1.4.2 比較strncmp
      • 1.4.3 比較memcmp
    • 1.5 搜尋
      • 1.5.1 搜尋memchr
      • 1.5.2 搜尋首次位置strchr
      • 1.5.3 逆匹配搜尋strcspn
      • 1.5.4 查詢第一個不屬於字符集的下標strspn
      • 1.5.5 查詢錯誤strerror
      • 1.5.6 查詢第一個屬於字符集位置strpbrk
      • 1.5.7 查詢給定字元的最後一次匹配strrchr
      • 1.5.8 查詢字串首次出現位置strstr
      • 1.5.9 分隔符查詢strtok
    • 1.6 排序&長度
      • 1.6.1 倒排strrev
      • 1.6.2 長度函式strlen
    • 1.7 轉換大小寫
      • 1.7.1 轉小寫strlwr
      • 1.7.2 轉大寫strupr
    • 1.8 轉換其他資料型別
      • 1.8.1 轉換浮點型atof
      • 1.8.2 轉換整型atoi
      • 1.8.3 轉換長整型
        • 1.8.3.1 atol
        • 1.8.3.2 strtol
        • 1.8.3.3 無符號長整型strtoul
      • 1.8.4 轉換雙精度strtod

1 字串處理函式

1.1 輸入輸出

1.1.1 輸出函式puts

函式puts將字串的內容輸出到終端,並將字串中的 \0 轉換成換行符 \n 。即輸出字串內容,並換行。例如:

char str[]="1234";
puts(str);
將輸出:1234

1.1.2 輸入函式gets

引數 str是字串,它的功能是從終端輸入—行字元到str中。其中輸入時的回車符被轉換成\0str不能是字串常量。該函式呼叫將返回一個函式值,其值是str的起始地址。

1.2 連線函式

1.2.1 stract

函式原型:char strcat (char dest,char *src);
函式功能:將兩個字串連線合併成一個字串,也就是把字串src連線到字串dest後面,連線後的結果放在字串dest中
返回值:指向字串dest的指標

引數 str1、str2 是字串,它的功能是將str2連線在str1的後面。str1不能是字串常量。函式呼叫返回一個函式值,函式值為str1的開始地址。正確使用該函式,要求str1必須足夠大,以便能容納str2的內容。注意,連線前,strl和str2都各有自\0。 連線後,strl中的\0在連線時被覆蓋掉,而在新的字串有效字元之後保留一個 \0 。例如:

char str1[100]="Beijing",str2[]="China";
strcat(str1,str2);
puts(str1);
將輸出BeijingChina。
#include <string.h>
#include <stdio.h>
int main( )
{
     char dest[20]={" "};
    char *hello = "hello ", *space = " ", *world = "world";
     strcat(dest, hello);
       strcat(dest, space);
    strcat(dest, world);
       printf("%s\n", destination);
    getch();
       return 0;
}
執行結果是:

hello world

注意:開始對字元陣列dest初始化為空是必要的,對宣告的變數進行初始化是一個很好的習慣,如果不對字元陣列dest進行初始化程式會產生執行時的錯誤,有興趣的讀者可以試試未初始化程式的輸出結果。

1.2.2 strncat

函式原型:char strncat (char dest, char *src, int n);
函式功能:將一個字串的子串連線到另一個字串末端,也就是把字串src的前n個字元連線到字串dest後面,連線後的結果放在字串dest中
返回值:指向字串dest的指標

#include <string.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
    char dest[30]={""};
    char *favorite = "I love", *tabs = "\t\n", *language = "C++";
    strcnat(dest, favorite,6);
    strncat(dest, tabs,1);
    strncat(dest, language,1);
    printf("%s\n", dest);
    getch();
    return 0;
}
執行結果是:

I love    C

注意:本例程中,字串tabs中的內容比較新奇,它並不是我們一般的字元,而是兩個轉義說明符構成的特殊字元,C語言內部在處理過程中遇到轉義說明符時會作特殊處理,本例中會將\t看做製表符,將\n看做換行符。

1.3 複製

1.3.1 複製strcpy

函式原型: char strcpy (char dest,char * src);
函式功能:實現字串的複製工作,也就是把字串src中的內容複製到字串dest中,使兩個字串的內容相同。
返回值:指向字串dest的指標

#include <stdio.h> 
#include <string.h> 
int main(void) { 
	char dest[20] ={""}; 
	char *src = "Hello World"; 
	int result; strcpy(dest,src); 
	printf("%s\n", dest); 
	result=strcmp(dest,src); 
	if(!result) 
		printf("dest is equal to src"); 
	else 
		printf("dest is not equal to src");
	getch(); 
	return 0; 

} 
執行結果是:

Hello World dest is equal to src 

注意:本例程中,向字元陣列中賦值時要保證字元陣列中有足夠的空間,雖然有時候即便空間不夠也會列印出正確的結果,但隨著程式的執行,不能保證超出下標範圍的部分還能以正確的型式存在。

1.3.2 複製strncpy

在某些應用中,需要將一個字串的前面一部分複製,其餘部分不複製。呼叫函式strncpy可實現這個要求。
strncpy(str1,str2,n)的作用是將str2中的前n個字元複製到str1(附加\0)。其中n是整型表示式,指明欲複製的字元個數。如果str2中的字元個數不多於n,則該函式呼叫等價於strcpy(strl,str2)

函式原型: char strncpy (char dest,char * src, int n);
函式功能:實現字串子串的複製工作,也就是把字串src中的前n個字元複製到字串dest中。
返回值:指向字串dest的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
    char dest[20]={""};
    char *src1="Hello World",*src2 ="Aloha";
    strncpy(dest,src1,5);
    strncpy(dest,src2,5);
    if(!strcmp(dest,src1))
        printf("dest is equal to src1");
    else if(!strcmp(dest,src2))
        printf("dest is equal to src2");
    else
        printf("dest is %s",dest);
    printf("%s\n", dest);
    getch();
    return 0;
}
執行結果是:

Aloha
dest is equal to src2

1.3.3 複製memcpy

函式原型:void memcpy(void destin, void *source, unsigned n)
函式功能:從source所指的物件中複製n個字元到destin所指的物件中。但是,如果這種複製發生在重疊物件之間,其行為是不可預知的。

#include <stdio.h>
#include <string.h>
int main(void)
{
   char *s = "";
   char *d = "This is a test for memcpy function";
   char *ptr;
   printf("destination before memcpy: %s\n", d);
   ptr = memcpy(d, s, strlen(s));
   if (ptr)
      printf("destination after memcpy: %s\n", d);
   else
      printf("memcpy failed\n");
   return 0;
}
執行結果為:
destination before memcpy: This is a test for memcpy function
destination after memcpy:  test for memcpy function

注意memcpystrcpy的不同在於應用memcpy進行字串的複製可以指定複製串的長度。另外memcpy的引數為void指標型別,因此它還可以對非字元型物件進行操作,而strcpy只適用於字串的複製。
如果複製過程中發生在重疊物件之間,其行為是不可預知的。例如下面這個例子:

#include <string.h>
#include <stdio.h>
int main(void)
{
  char *d = "1234567890";
  char *p;
  p=d+3;
  printf(" %s\n", d);
  memcpy(p, d, 6);
  printf(" %s\n", d);
  return 0;
}

執行結果為:
1234567890
1231231230

由於字串p是字串d的一個子串,在呼叫memcpy時,複製的字串在d和p之間又重疊,因此該複製行為是不可預知的,結果也自然難以保證。
顯然這不是期望得到的結果。

1.3.4 指定複製memmove

函式原型:void memmove(void destin, void *source, unsigned n)
函式功能:從source所指的物件中複製n個字元到destin所指的物件中。與memcpy不同的是,當物件重疊時,該函式仍能正確執行。

#include <stdio.h>
#include <string.h>
int main(void)
{
   char *s = "";
   char *d = "This is a test for memcpy function";
   char *ptr;
   printf("destination before memmove: %s\n", d);
   ptr = memmove(d, s, strlen(s));
   if (ptr)
      printf("destination after memmove:  %s\n", d);
   else
      printf("memcpy failed\n");
   return 0;
}
執行結果為:
destination before memmove: This is a test for memcpy function
destination after memmove:  test for memcpy function

注意: 與函式memcpy不同的是,當物件重疊時,該函式仍能正確執行。例如下面這個例子:

#include <string.h>
#include <stdio.h>
int main(void)
{
  char *d = "1234567890";
  char *p;
  p=d+3;
  printf(" %s\n", d);
  memmove(p, d, 6);
  printf(" %s\n", d);
  return 0;
}
執行結果為:

1234567890
1231234560

顯然這是期望得到的結果。 這是因為函式memmove的複製行為類似於先從source物件中複製n個字元到一個與source和destin都不重合的含n個字元的臨時陣列中作為緩衝,然後從臨時陣列中再複製n個字元destin所指的物件中。 就本段程式而言,memmove先將字串“123456”複製到一個臨時陣列中,再將它複製到以p為首地址的字串中。

1.3.5 指定複製memset

函式原型:void memset(void s, int c, unsigned n)
函式功能:把c複製到s所指向的物件的前n個字元的每一個字元中。
返回值:s的值

#include <string.h>
#include <stdio.h>
int main(void)
{
   char *str="AAAAAAAAAAAAAAAAAA";
   printf("The original string is:    %s\n",str);
   memset(str,'B',9);
   printf("The string after memset is:%s\n",str);
}
執行結果為:

The original string is:    AAAAAAAAAAAAAAAAAA
The string after memset is:BBBBBBBBBAAAAAAAAA

1.3.6 新建複製strdup

函式原型:char strdup(char str);
函式功能:將字串複製到新分配的空間位置,也就是將str複製到一塊新分配的儲存空間,其內部使用動態分配記憶體技術實現的,分配給字串的空間來自於當前所用記憶體模式制定的堆。
返回值:返回指向含有該串複製的儲存區

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *src="This is the buffer text";
    char *dest;
    dest=strdup(src);
    if(!strcmp(src,dest))
        printf("Copy success\n%s\n",dest);
    else
        printf("Copy failure");
    free(dest);
    getch();
    return 0;
}
執行結果是:

Copy success
This is the buffer text

注意:本例程中,初學者往往會忽視釋放動態分配儲存區的操作,雖然表面看起來似乎對程式沒有什麼影響,但實際上不對儲存區進行回收會造成記憶體洩漏,在一些大程式會造成致命的後果。

1.3.7 字串設定strset

函式原型:char strset(char str, char c);
函式功能:將字串原有字元全部設定為指定字元,也就是將字串str中的所有字元全部用字元c進行替換.
返回值:返回指向被替換字串的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
   char str[11]="0123456789";
   char symbol='a';
   printf("Before: %s\n",str);
   strset(str,symbol);
   printf("After: %s\n",str);
   getch();
   return 0;
}
執行結果是:

0123456789
aaaaaaaaaa

1.4 比較

1.4.1 比較strcmp

函式原型:int strcmp (char str1,char str2);
函式功能:比較兩個字串的大小,也就是把字串str1和字串str2從首字元開始逐字元的進行比較,直到某個字元不相同或比較到最後一個字元為止,字元的比較為ASIC碼的比較
返回值:若字串str1大於字串str2返回結果大於零,若字串str1小於字串str2返回結果小於零,若字串str1等於字串str2返回結果等於零

引數 str1、str2 是字串,它的功能是比較兩個字串大小。對兩個字串自左至右逐個字元相比較(按字元的ASCII程式碼值的大小),直至出現不同的字元或遇到\0為止。如全部字元都相同,則認為相等,函式返回0值;若出現不相同的字元,則以這第一個不相同的字元比較結果為準。若str1的那個不相同字元小於str2的相應字元,函式返回一個負整數;反之,返回一個正整數。 注意,對字串不允許施加相等==和不相等!=運算,必須用字串比較函式對字串作比較。
例如:
if(str1==str2) printf("Yes\n");是非法的,而只能用if(strcmp(str1,str2)==0) printf("Yes\n");

#include <string.h>
#include <stdio.h>
int main(void)
{
    char *str1 = "Canada", *str2 = "China", *str3 = "china";
    int result;
    result = strcmp(str1, str2);
    if (result < 0)
        printf("%s is less than %s", str1,str2);
    else
        printf("%s is not less than %s", str1,str2);
    printf("\n");
    result = strcmp(str2, str3);
    if (result < 0)
        printf("%s is less than %s", str2,str3);
    else
        printf("%s is not less than %s", str2,str3);
    getch();
    return 0;
}

執行結果是:
Canada is less than China
China is less than china

注意:本例程中,字串的比較結果為首個兩個不等字元之間ASIC碼的差值,如果我們將第一次比較的結果result輸出,應該是' a'的ASIC與碼與' h'的ASIC碼的差值

1.4.2 比較strncmp

函式原型: int strncmp (char str1,char str2, int n);
函式功能:比較兩個字串子串的大小,也就是把字串str1的前n個字元組成的子串和字串str2的前n個字元組成的子串進行比較,從首字元開始逐字元的進行比較,直到某個字元不相同或比較到第n個字元為止。
返回值:若字串str1前n個字元組成的子串大於字串str2前n個字元組成的子串返回結果大於零,若字串str1前n個字元組成的子串小於字串str2前n個字元組成的子串返回結果小於零,若字串str1前n個字元組成的子串等於字串str2前n個字元組成的子串返回結果等於零

#include <string.h>
#include <string.h>
int main(void)
{
    char *str1="Hello World";
    char *str2="Hello C Programme";
    int result;
    result=strncmp(str1,str2,5);
    if(!result)
        printf("%s is identical to %s in the first 5 words",str1,str2);
    else if(result<0)
        printf("%s is less than %s in the first 5 words",str1,str2);
    else
        printf("%s is great than %s in the first 5 words",str1,str2);
    printf("\n");
    result=strncmp(str1,str2,10);
     if(!result)
        printf("%s is identical to %s in the first 10 words",str1,str2);
    else if(result<0)
        printf("%s is less than %s in the first 10 words",str1,str2);
    else
        printf("%s is great than %s in the first 10 words",str1,str2);
    getch();
    return 0;
}
執行結果是:

Hello World is identical to Hello C Programme in the first 5 words
Hello World is great than Hello C Programme in the first 10 words

注意:本例程中,要注意子串比較的過程中子串的大小應不小於零且不超過字串的長度,雖然子串的長短引數不會產生編譯時的錯誤和最終結果的輸出,但在比較前檢查比較範圍是一個很好的習慣。

1.4.3 比較memcmp

函式原型:void memcmp(char s1, char *s2, unsigned n)
函式功能:比較s1所指向的字串與s2所指向的字串的前n個字元。
返回值:根據s1所指向的物件的大於、等於、小於s2所指向的物件,函式

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *str1="ABCDEF";
    char *str2="ABCDEf";
    int s1,s2;
    s1=memcmp(str1,str2,6);
    s2=memcmp(str1,str2,5);
    printf("The comparison of 6 character\n");
    if(s1>0)printf("%s>%s\n",str1,str2);
    else
        if(s1<0)printf("%s<%s\n",str1,str2);
    else
         printf("%s=%s\n",str1,str2);
    printf("The comparison of 5 character\n");
    if(s2>0)printf("%s>%s\n",str1,str2);
    else
        if(s2<0)printf("%s<%s\n",str1,str2);
    else
         printf("%s=%s\n",str1,str2);
}

執行結果為:
The comparison of 6 character
ABCDEF<ABCDEf
The comparison of 5 character
ABCDEF=ABCDEf

注意: 由於字串比較的方法是從左至右按照字元的ASCII碼進行比較的,因此在比較6個字元時,字串“ABCDEF”<“ABCDEf”(f的ASCII值大於F的ASCII值);而只比較5個字元時,字串“ABCDEF”=“ABCDEf”。

1.5 搜尋

1.5.1 搜尋memchr

函式原型:void memchr(void s, char ch, unsigned n)
函式功能:在陣列的前 n 個位元組中搜尋字元 ch
返回值:返回一個指標,它指向ch在s 中第一次出現的位置。如果在s的前n個字元中找不到匹配,返回NULL。

#include <string.h>
#include <stdio.h>
int main(void)
{
   char *str="I love China\n";
   char *p;
   p=memchr(str,'C',strlen(str));
   if(p)
         printf("%s",p);
   else
        printf("The character was not found\n") ;
}
本例程的執行結果為:
China

1.5.2 搜尋首次位置strchr

函式原型:char strchr(char str, char c);
函式功能:在字串中查詢給定字元的第一次匹配,也就是在字串str中查詢字元c第一次出現的位置
返回值:第一次匹配位置的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
    char str[15] ={""};
    char *ptr, c = 'r';
    strcpy(str, "Hello World");
    ptr = strchr(str, c);
    if (ptr)
       printf("The character %c is at position: %d\n", c, ptr-str);
    else
       printf("The character was not found\n");
    strcpy(str, "Aloha");
    if (ptr)
       printf("The character %c is at position: %d\n", c, ptr-str);
    else
       printf("The character was not found\n");
    getch();
    return 0;
}
執行結果是:
The character r is at position 8
The character r is at position 8

注意:本例程中,對字串中字元匹配的返回值是指向匹配位置的指標,我們獲取到該指標後,與陣列的頭指標做減法,也就是與陣列變數名做減法,就可以獲得我們得到的指標在陣列中對應的下標。

1.5.3 逆匹配搜尋strcspn

函式原型:int strcspn(char str1, char str2);
函式功能:在字串中查詢第一個屬於字符集的下標,即從開始有多少個字元不屬於字符集,也就是在字串str1中查詢第一個屬於字符集str2中任何一個字元的下標,即字串str1中從開始一直有多少個字元不屬於字符集str2中的字元。
返回值:所找到的字串中段的長度

#include <string.h>
#include <stdio.h>
int main(void)
{
    char *str1="tomato",*str2="carrot";
    char *str= "abc";
    int  result;
    result = strcspn(str1,str);
    if(result)
        printf("The first %d is congruent\n",result);
    else
        printf("No character is congruent\n");
    result = strcspn(str2,str);
    if(result)
        printf("The first %d is congruent\n",result);
    else
        printf("No character is congruent\n");
    getch();
    return 0;
}

執行結果是:
The first 3 is congruent
No character is congruent

注意:本例程中,字符集逆匹配與字符集匹配兩者的匹配方式截然相反,字串匹配是當字串中字元等於字符集中任意字元是匹配成功,字串逆匹配是當字串中字元不等於字符集中任意字元是匹配成功。

1.5.4 查詢第一個不屬於字符集的下標strspn

函式原型:int strspn(char str1, char str2);
函式功能:在字串中查詢第一個不屬於字符集的下標,即從開始有多少個字元屬於字符集,也就是在字串str1中查詢第一個不屬於字符集str2中任何一個字元的下標,即字串str1中從開始一直有多少個字元屬於字符集str2中的字元。
返回值:所找到的字串中段的長度

#include <string.h>
#include <stdio.h>
int main(void)
{
    char *str1="cabbage",*str2="potato";
    char *str= "abc";
    int  result;
    result = strspn(str1,str);
    if(result)
        printf("The first %d is congruent\n",result);
    else
        printf("No character is congruent");
    result = strspn(str2,str);
    if(result)
        printf("The first %d is congruent\n",result);
    else
        printf("No character is congruent");
    getch();
    return 0;
}
執行結果是:

The first 5 is congruent
No character is congruent

1.5.5 查詢錯誤strerror

函式原型:char *strerror(int errnum);
函式功能:獲取程式出現錯誤的字串資訊,也就是根據錯誤程式碼errnum查詢到具體的錯誤資訊。

如下示例,迴圈只取了前十二種錯誤資訊,實際的錯誤種類還有更多

#include <stdio.h>
#include <errno.h>
int main(void)
{
    char *error;
    int i;
    for(i=0;i<12;i++)
    {
        error=strerror(i);
        printf("%s",error);
    }
    getch();
    return 0;
}

執行結果是:

Error 0
Invalid function number
No such file or directory
Path not found
Too many open files
Permission denied
Bad file number
Memory arena trashed
Not enough memory
Invalid memory block address
Invalid environment
Invalid format

1.5.6 查詢第一個屬於字符集位置strpbrk

函式原型:char strpbrk(char str1, char *str2);
函式功能:在字串中查詢第一個屬於字符集的字元位置,也就是在字串str1中查詢第一個屬於字符集str2中任意字元的位置。
返回值:返回第一個匹配字元的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *str1="There are 5 pigs in the hogpen";
    char *str2="0123456789";
    char *result;
    result = strpbrk(str1,str2);
    if(result)
        printf("%s\n",result++);
    else
        printf("There are no numbers any more");
    result = strpbrk(result,str2);
    if(result)
        printf("%s\n",result++);
    else
        printf("There are no numbers any more");
    getch();
    return 0;
}
執行結果是:

5 pigs in the hogpen
There are no numbers any more

注意:本例程中,值得注意的是匹配成功時結果的輸出。由於獲得了匹配成功的字元的指標,因此我們可以利用該指標輸出字串的字串,利用自增運算子我們移動一個位置又可以對尚未匹配的子串繼續進行下一次匹配。

1.5.7 查詢給定字元的最後一次匹配strrchr

函式原型:char strrchr(char str, char c);
函式功能:在字串中查詢給定字元的最後一次匹配,也就是在字串str中查詢字元c最後一次出現的位置
返回值:最後一次匹配位置的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
    char str[15]={""};
    char *ptr, c = 'o';
    strcpy(str, "Hello World");
    ptr = strchr(str, c);
    if (ptr)
       printf("The first character %c is at position: %d\n", c, ptr-str);
    else
       printf("The character was not found\n");
    ptr = strrchr(str, c);
    if (ptr)
       printf("The last character %c is at position: %d\n", c, ptr-str);
    else
       printf("The character was not found\n");
    getch();
    return 0;
}
執行結果是:

The first character r is at position 4
The last character r is at position 7

注意:本例程中,如果字串中只有一個'o'字元,那麼無論呼叫哪種字串中字元匹配函式都會返回相同的結果。

1.5.8 查詢字串首次出現位置strstr

函式原型:char strstr(char str1, char *str2);
函式功能:在字串中查詢另一個字串首次出現的位置,也就是在字串str1中查詢第一次出現字串str2的位置。
返回值:返回第一次匹配字串的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *str1 = "Borland International",*str2 = "nation";
    char *result;
    result=strstr(str1, str2);
    if(result)
        printf("The substring is: %s\n", ptr);
    else
        printf("Not found the substring");
    getch();
    return 0;
}
執行結果是:
The substring is national

注意:本例程中,匹配成功時的返回結果並不是進行匹配的字串,而是第一次匹配成功的字串首字元的指標。

1.5.9 分隔符查詢strtok

函式原型:char strtok(char str1, char *str2);
函式功能:在字串中查詢單詞,這個單詞始有第二個字串中定義的分隔符分開,也就是在字串str1中查詢由字串str2定義的分隔符,以分隔符為界,分隔出來的分隔符前面的所有字元組成一個單詞,分離出第一個單詞後將第一個引數置為空,可以繼續分隔第二個單詞。
返回值:返回分隔出的單詞的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *str1="I am very\thappy,to,stduy\nC\nprogramme";
    char *str2=" ,\t\n";
    char *token;
    printf("%s\n\nTokens:\n",str1);
    token = strtok(str1,str2);
    while( token != NULL )
    {
        printf("%s\n",token);
        token = strtok(NULL,str2);
    }
    getch();
    return 0;
}

執行結果是:

I am very        happy,to,study
C
Programme
Token:
I
am
very
happy
to
study
C
Programme

注意:本例程中,一定要記住如果在第一次分隔出單詞後想繼續進行分隔操作,務必要將函式的第一個引數置為空。

1.6 排序&長度

1.6.1 倒排strrev

函式原型:char strrev(char str);
函式功能:將字串進行倒轉,也就是將字串str中的第一個字元與最後一個字元交換,第二個字元與倒數第二個字元交換,以此類推。
返回值:返回倒轉後字串的指標

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *str = "Able was I ere I saw Elba";
    printf("Before: %s\n",str);
    strrev(str);
    printf("After: %s\n",str);
    getch();
    return 0;
}
執行結果是:

Able was I ere I saw Elba
ablE was I ere I saw elbA

注意:本例程中,字元陣列中的初值並不是嚴格意義上的迴文,將它倒轉後會發現與原字串並不是完全一樣。

1.6.2 長度函式strlen

函式原型: int strlen (char *str);
函式功能:求字串的長度,也就是求字串str中有多少個字元
返回值:字串str字元的個數

#include <stdio.h>
#include <string.h>
int main(void)
{
    char src1[3]={""},src2[10]={"Hello"};
    char *src3="Hello";
    printf("%d\n",strlen(src1));
    printf("%d\n",strlen(src2));
    printf("%d\n",strlen(src3));
    getch();
    return 0;
}
執行結果是:

0
5
5

1.7 轉換大小寫

1.7.1 轉小寫strlwr

函式原型:char strlwr(char str,);
函式功能:將字串原有大寫字元全部轉換為小寫字元,也就是將字串str中的所有字元變成小寫。
返回值:返回指向被轉換字串的指標

函式strlwr(str)將字串str中的大寫字母轉換成小寫字母,其中str不能是字串常量。 例0.24:任意輸入一個英文書名,將書名中的小寫字母全部轉換成大寫字母,其餘字元不變,輸出轉換後的書名。程式程式碼如下:

#include <stdio.h>
#include <string.h>
int main()
{
    char str[100];
    int i;
    printf("Input the book name: ");
    gets(str);
    for(i=0; i<=strlen(str);i++){
	    if(str[i]>='a'&&str[i]<='z')
	    str[i]-=32;
	 }
   puts(str);
   return 0; 
}

在上面的程式中,首先定義了一個字元陣列str,用來儲存英文書名,然後用gets函式得到輸入的英文書名。在for迴圈中,用strlen函式得到輸入的英文書名字串的長度,然後把英文書名的小寫字母轉換成大寫字母。最後用puts函式輸出轉換後的英文書名。

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *s="You'll Never Walk Alone";
    printf("%s",strlwr(s));
    getch();
    return 0;
}

1.7.2 轉大寫strupr

函式原型:char strupr(char str);
函式功能:將字串原有小寫字元全部轉換為大寫字元,也就是將字串str中的所有字元變成大寫。
返回值:返回指向被轉換字串的指標

strupr(str)則將字串str中的小寫字母轉換成大寫字母,其中str不能是字串常量。

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *s=" You'll Never Walk Alone ";
    printf("%s",strlwr(s));
    getch();
    return 0;
}

執行結果是:

YOU’LL NEVER WALK ALONE

1.8 轉換其他資料型別

1.8.1 轉換浮點型atof

函式原型:float atof(const char *str);
函式功能:將字串轉換成浮點值,也就是將字串str轉換成浮點值然後獲取轉換後的結果。
返回值:返回轉換後的浮點值

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
   char *str="12345.67";
   float result;
   result=atof(str);
   printf("string=%s\nfloat =%f\n",str,result);
   getch();
   return 0;
}
執行結果:
string =12345.67
float=12345.669922

注意:本例程中,轉換成浮點數的結果有些奇怪,它並不等於我們字串中變數的值,而是存在一定的誤差,雖然誤差很小,但是可以看出誤差是從原字串中的最後一位開始的,這是由於在轉換過程中函式內部在實現時採用的轉換方式造成的,如果想避免這種誤差,可以使用strtoX系列函式。

1.8.2 轉換整型atoi

函式原型:int atoi(const char *str);
函式功能:將字串轉換成整數值,也就是將字串str轉換成整型值然後獲取轉換後的結果。
返回值:返回轉換後的整型值

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
   char *str="12345.67";
   int result;
   result=atoi(str);
   printf("string=%s\ninteger=%d\n",str,result);
   getch();
   return 0;
}

執行結果是:
string =12345.67
integer=12345

1.8.3 轉換長整型

1.8.3.1 atol

函式原型:long atol(const char *str);
函式功能:將字串轉換成長整數值,也就是將字串str轉換成長整型值然後獲取轉換後的結果。
返回值:返回轉換後的長整型值

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
   char *str="12345.67";
   long result;
   result=atol(str);
   printf("string=%s\nlong =%ld\n",str,result);
   getch();
   return 0;
}

執行結果是:
string =12345.67
long=12345

1.8.3.2 strtol

函式原型:long strtol(char str, char *endptr, int base);
函式功能:將字串轉換為長整型值,也就是將字串str轉換為長整型值,其中進行轉換字串必須是長整型的字元表示格式,如果字串中有非法的非數字字元,則第二個引數將負責獲取該非法字元,即字串指標endptr用於進行錯誤檢測,轉換在此非法字元處停止進行。
返回值:返回轉換後的長整型結果

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
    char str[20], *endptr;
    long result;
    while(1)
    {
        printf("Input a long:");
        gets(str);
        result=strtod(str,&endptr);
        if(result!=-1)
            printf("The number is %ld\n",result);
        else
            break;
    }
    getch();
    return 0;
}
執行結果是:

Input a long: -15
The number is -15
Input a long: 1234.5678
The number is 1234
Input a long: 333333333333
The number is 2147483647
Input a long: -34abc
The number is -34
Input a long: abc
The number is 0
Input a float: -1

注意:將字串中的小數轉換為長整型時,程式會將小數點看作非法字元,從而停止轉換繼續進行,因此無論小數點後面的數是多少都會截斷,而不是我們習慣上的四捨五入或者五舍六入。

1.8.3.3 無符號長整型strtoul

函式原型:unsigned long strtoul(char str, char *endptr, int base);
函式功能:將字串轉換為無符號長整型值,也就是將字串str轉換為無符號長整型值,其中進行轉換字串必須是無符號長整型的字元表示格式,如果字串中有非法的非數字字元,則第二個引數將負責獲取該非法字元,即字串指標endptr用於進行錯誤檢測,轉換在此非法字元處停止進行。
返回值:返回轉換後的無符號長整型結果

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
    char str[20], *endptr;
    unsigned long result;
    while(1)
    {
        printf("Input an unsigned long:");
        gets(str);
        result=strtoud(str,&endptr);
        if(result!=-1)
            printf("The number is %lu\n",result);
        else
            break;
    }
    getch();
    return 0;
}

執行結果是:

Input a long: 100
The number is 100
Input a long: -36
The number is 0
Input a float: 1

注意:本例程中,輸入負數的時候程式會將負號看作非法字元,從而停止轉換繼續進行,沒有發生任何實際的轉換。

1.8.4 轉換雙精度strtod

函式原型:double strtod(char str, char *endptr);
函式功能:將字串轉換非雙精度值,也就是將字串str轉換為雙精度值,其中進行轉換字串必須是雙精度數的字元表示格式,如果字串中有非法的非數字字元,則第二個引數將負責獲取該非法字元,即字串指標endptr用於進行錯誤檢測,轉換在此非法字元處停止進行。
返回值:返回轉換後的雙精度結果

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
    char str[20], *endptr;
    double result;
    while(1)
    {
        printf("Input a float:");
        gets(str);
        result=strtod(str,&endptr);
        if(result==-1)
            printf("The number is %lf\n",str,result);
        else
            break;
    }
    getch();
    return 0;
}

執行結果是:

Input a float: 4.2
The number is 4.20000
Input a float: 79
The number is 79.00000
Input a float: 1.1111111111
The number is 1.111111
Input a float: 34.45abc
The number is 34.450000
Input a float:abc
The number is 0.000000
Input a float: -1

注意:本例程中,即便轉換出現非法字元迴圈也不會停止,而只是透過第二個引數捕捉到了非法字元,可以編寫程式對非法字元進行處理,本例中並沒有這樣做,迴圈只是以輸入迴圈結束標誌迴圈結束依據。

相關文章