C语言再学习 -- 字符串和字符串函数
最近身體很不給力,很乏累!白天沒精神,晚上睡不著,心情還很煩躁。看書都有點(diǎn)看不下去的樣子,到了C語言最難掌握的部分了,數(shù)組、指針、字符串。硬著頭皮看書總結(jié)吧。
一、字符串
1、字符串介紹
字符串是以空字符(\0)結(jié)尾的char數(shù)組,例如:
char ar[20] = "hello world"; ? ??
2、定義字符串
字符常量,又稱字符串文字,是指位于一對雙引號(hào)中的任何字符。雙引號(hào)里的字符加上編譯器自動(dòng)提供的結(jié)束標(biāo)志(\0)字符,作為一個(gè)字符串被存儲(chǔ)在內(nèi)存里。
?
#include <stdio.h> int main (void) {char ar1[50] = "hello" " " "world""!";char ar2[50] = "hello world!";printf ("%s\n", ar1);printf ("%s\n", ar2);printf ("\"We are family!\"\n");return 0; } 輸出結(jié)果: hello world! hello world! "We are family!"3、字符串初始化
定義一個(gè)字符串?dāng)?shù)組時(shí),必須讓編譯器知道它需要多大空間。
方法一,指定一個(gè)足夠大的數(shù)組來容字符串
char ar[20] = "hello world";
char ar[2+5]; ? /*數(shù)組大小也可以是常量表達(dá)式*/
指定數(shù)組大小時(shí),一定要確保數(shù)組元素?cái)?shù)比字符串長度至少多1(多出來的1個(gè)元素用于容納空字符),未被使用的元素均被自動(dòng)初始化為0。這里的0是char形式的空字符,不是數(shù)字字符0.
方法二,讓編譯器決定數(shù)組大小
char ar[] = "hello world";
char ar[] = {'h' ,'e' ,'l' ,'l' ,'o' ,' ' ,'w' ,'o' ,'r' ,'l' ,'d' ,'\0'};
注意:標(biāo)示結(jié)束的空字符。如果沒有它,得到的就只是一個(gè)字符數(shù)組而不是一個(gè)字符串。
注意區(qū)分:數(shù)字字符 0,空字符 \0,空格 ' ',空指針 NULL。
方法三,指針初始化字符串
char * str = "hello world";
說明:數(shù)組和指針初始化字符串的區(qū)別
數(shù)組初始化是從靜態(tài)存儲(chǔ)區(qū)把一個(gè)字符串復(fù)制給數(shù)組,而指針初始化只是復(fù)制字符串的地址。其主要區(qū)別在于數(shù)組名ar是一個(gè)常量,而指針str則是一個(gè)變量。如,只有指針變量可以進(jìn)行 str++。數(shù)組的元素是變量(除非聲明數(shù)組時(shí)帶有關(guān)鍵字const),但是數(shù)組名不是變量。如,*(ar + 2) = 'm'; ?是可以的。
擴(kuò)展,區(qū)分單個(gè)字符和字符串
用單引號(hào)引起的一個(gè)字符實(shí)際上代表一個(gè)整數(shù),整數(shù)值對應(yīng)于該字符子啊編譯器采用的字符集中的序列值。因此,對于采用 ASCII 字符集的編譯器而言,'a' 的含義與 0141(八進(jìn)制)或者97(十進(jìn)制)嚴(yán)格一致。
用雙引號(hào)引起的字符串,代表的卻是一個(gè)指向無名數(shù)組起始字符的指針,該數(shù)組被雙引號(hào)之間的字符以及一個(gè)額外的二進(jìn)制值為零的字符 '\0' 初始化。
#include <stdio.h> #include <string.h> #include <stdlib.h> int main (void) { char *str1 = "abcde"; char str2[] = "abcde"; char str3[8] = "abcde"; char str4[] = {'a', 'b', 'c', 'd', 'e'}; char *p1 = malloc (20); printf ("sizeof (str1) = %d, strlen (str1) = %d\n", sizeof (str1), strlen (str1)); printf ("sizeof (*str1) = %d, strlen (str1) = %d\n", sizeof (*str1), strlen (str1)); printf ("sizeof (str2) = %d, strlen (str2) = %d\n", sizeof (str2), strlen (str2)); printf ("sizeof (str3) = %d, strlen (str3) = %d\n", sizeof (str3), strlen (str3)); printf ("sizeof (str4) = %d, strlen (str4) = %d\n", sizeof (str4), strlen (str4)); printf ("sizeof (p1) = %d, sizeof (*p1) = %d\n", sizeof (p1), sizeof (*p1)); printf ("sizeof (malloc(20)) = %d\n", sizeof (malloc (20))); return 0; } 輸出結(jié)果: sizeof (str1) = 4, strlen (str1) = 5 sizeof (*str1) = 1, strlen (str1) = 5 sizeof (str2) = 6, strlen (str2) = 5 sizeof (str3) = 8, strlen (str3) = 5 sizeof (str4) = 5, strlen (str4) = 5 sizeof (p1) = 4, sizeof (*p1) = 1 sizeof (malloc(20)) = 4根據(jù)上面的例子,可知 str1、str2以空字符(\0)結(jié)尾是字符串。而 str4 不是字符串。
如果兩者混用,那么編譯器的類型檢查功能將會(huì)檢測到這樣的錯(cuò)誤:
?
#include <stdio.h> #include <string.h>int main (void) {char *str = '2';return 0; } 輸出結(jié)果: 警告: 初始化時(shí)將整數(shù)賦給指針,未作類型轉(zhuǎn)換 [默認(rèn)啟用] #include <stdio.h> #include <string.h>int main (void) {printf ("1111111\n");printf ('\n');printf ("2222222\n");return 0; } 輸出結(jié)果: test.c: 在函數(shù)‘main’中: test.c:7:2: 警告: 傳遞‘printf’的第 1 個(gè)參數(shù)時(shí)將整數(shù)賦給指針,未作類型轉(zhuǎn)換 [默認(rèn)啟用] /usr/include/stdio.h:363:12: 附注: 需要類型‘const char * __restrict__’,但實(shí)參的類型為‘int’ test.c:7:2: 警告: 格式字符串不是一個(gè)字面字符串而且沒有待格式化的實(shí)參 [-Wformat-security]還有需要注意的,在用雙引號(hào)括起來的字符串中,注釋符 /* 屬于字符串的一部分,而在注釋中出現(xiàn)的雙引號(hào) "" 又屬于注釋的一部分。
#include <stdio.h> #include <string.h>int main (void) {char *str = "123/*ddddd*/456";printf ("%s\n", str);/*"123456"*/return 0; } 輸出結(jié)果: 123/*ddddd*/456再再有注意宏定義,用于定義字符串,尤其是路徑
A),#define ENG_PATH_1 E:\English\listen_to_this\listen_to_this_3 ? ? ? ? ? ? ??
B),#define ENG_PATH_2 “ E:\English\listen_to_this\listen_to_this_3”
A 為 定義路徑, B ?為定義字符串
4、字符串輸入/輸出
參看:C語言再學(xué)習(xí) 13--輸入/輸出
二、字符串函數(shù)
經(jīng)過了一個(gè)月的Hi3516A的項(xiàng)目,現(xiàn)在終于有時(shí)間,靜下心來繼續(xù)總結(jié)C語言了。雖說過了一個(gè)月,總結(jié)到什么地方了、還有什么沒總結(jié)的地方,基本上忘得差不多了,慢慢拾起來吧!
字符串函數(shù),其原型在/kernel/include/linux/string.h有聲明
這類字符串庫函數(shù)的功能實(shí)現(xiàn)函數(shù)的答案在內(nèi)核源碼/kernel/lib/string.c
擴(kuò)展:size_t類型為unsigned int類型,占位符使用%u或%lu,C99用%zd。
下面來介紹一些最有用和最常用的函數(shù):
1、strlen() 函數(shù)
#include <string.h>
size_t strlen(const char *s);
函數(shù)功能:用來統(tǒng)計(jì)字符串中有效字符的個(gè)數(shù)
功能實(shí)現(xiàn)函數(shù):
size_t strlen (const char *s) {const char *sc;for (sc = s; *sc != '\0'; ++sc)/"nothing"/return sc - s; }strlen()函數(shù)被用作改變字符串長度,例如:
?
#include <stdio.h> #include <string.h> void fit (char *, unsigned int); int main (void) {char str[] = "hello world";fit (str, 7);puts (str);puts (str + 8);return 0; }void fit (char *string, unsigned int size) {if (strlen (string) > size)*(string + size) = '\0'; } 輸出結(jié)果: hello w rld可以看出:fit()函數(shù)在數(shù)組的第8個(gè)元素中放置了一個(gè)'\0'字符來代替原有的o字符。puts()函數(shù)輸出停在o字符處,忽略了數(shù)組的其他元素。然而,數(shù)組的其他元素仍然存在。
puts (str + 8);
表達(dá)式str + 8是str[8]即'r'字符的地址。因此puts()顯示這個(gè)字符并且繼續(xù)輸出知道遇到原字符串中的空字符。
2、strcat()函數(shù)
#include <string.h>
char *strcat(char *dest, const char *src);
函數(shù)功能:合并兩個(gè)字符串
缺點(diǎn):超出字符串存儲(chǔ)區(qū)范圍的話,有可能修改數(shù)組以外的存儲(chǔ)區(qū)這會(huì)導(dǎo)致嚴(yán)重錯(cuò)誤
功能實(shí)現(xiàn)函數(shù):
char *strcat(char *dest, const char *src) {char *tmp = dest;while (*dest)dest++;while ((*dest++ = *src++) != '\0');return tmp; }strcat()函數(shù)它將第二個(gè)字符串的一份拷貝添加到第一個(gè)字符串的結(jié)尾,從而使第一個(gè)字符串成為一個(gè)新的組合字符串,第二個(gè)字符串并沒有改變,例如:
#include <stdio.h> #include <string.h> #define SIZE 80 int main (void) {char flower[SIZE];char addon[]= " is beautiful";gets (flower);strcat (flower, addon);puts (flower);return 0; } 輸出結(jié)果: rose rose is beautiful3、strncat()函數(shù)
上面有提到strcat()函數(shù)的缺點(diǎn),它并不能檢查第一個(gè)數(shù)組是否能夠容納第二個(gè)字符串。如果沒有為第一個(gè)數(shù)組分配足夠大的空間,多出來的字符溢出到相鄰存儲(chǔ)單元時(shí)就會(huì)出現(xiàn)問題。
#include <string.h>
?char *strncat(char *dest, const char *src, size_t n);
函數(shù)功能:合并兩個(gè)字符串
功能實(shí)現(xiàn)函數(shù):
char *strncat(char *dest, const char *src, size_t count) {char *tmp = dest;if (count) {while (*dest)dest++;while ((*dest++ = *src++) != 0) {if (--count == 0) {*dest = '\0';break;}}}return tmp; }例如:
#include <stdio.h> #include <string.h> #define SIZE 30 #define BUGSIZE 13 int main (void) {char flower[SIZE];char addon[]= " is beautiful";char bug[BUGSIZE];int arg;puts ("what is your favorite flower");gets (flower);if ((strlen (addon) + strlen (flower) + 1) <= SIZE)strcat (flower, addon);puts (flower);puts ("what is your favorite flower");gets (bug);arg = BUGSIZE - strlen (bug) -1;strncat (bug, addon, arg);puts (bug);return 0; } 輸出結(jié)果: what is your favorite flower Rose Rose is beautiful what is your favorite flower MuDan MuDan is bea4、strcmp()函數(shù)
#include <string.h>
int strcmp(const char *s1, const char *s2);
函數(shù)功能:比較兩個(gè)字符串的大小,比較依據(jù)的是ASCII碼
返回值:依次比較字符串每一個(gè)字符的ASCII碼,如果兩個(gè)字符串參數(shù)相同,返回0;如果第一個(gè)字符串參數(shù)較大,則返回1,如果第二個(gè)字符串較大,則返回-1。
功能實(shí)現(xiàn)函數(shù):
int strcmp(const char *cs, const char *ct) {unsigned char c1, c2;while (1) {c1 = *cs++;c2 = *ct++;if (c1 != c2)return c1 < c2 ? -1 : 1;if (!c1)break;}return 0; }需要注意的是:
strcmp()函數(shù)比較的是字符串,而不是數(shù)組和字符。它可以用來比較存放在不同大小數(shù)組里的字符串。
#include <stdio.h> #include <string.h> #define SIZE 30 #define STOP "q" int main (void) {char str[SIZE];while (gets (str) != NULL && strcmp (str, STOP)){printf ("hello\n");sleep (1);}return 0; }
這里提一下:strcmp比較區(qū)分字母大小寫 相當(dāng)是比較的時(shí)候純粹按照ascii碼值來比較從頭到尾。
而 stricmp 是不區(qū)分字母的大小寫的。
?
5、strncmp()函數(shù)
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
函數(shù)功能:只比較兩個(gè)字符串里前n個(gè)字符
功能實(shí)現(xiàn)函數(shù):
int strncmp(const char *cs, const char *ct, size_t count) {unsigned char c1, c2;while (count) {c1 = *cs++;c2 = *ct++;if (c1 != c2)return c1 < c2 ? -1 : 1;if (!c1)break;count--;}return 0; }6、strcpy()函數(shù)
#include <string.h>
char *strcpy(char *dest, const char *src);
函數(shù)功能:把一個(gè)字符串復(fù)制到另外一個(gè)字符數(shù)組里
缺點(diǎn):有可能修改不屬于數(shù)組的存儲(chǔ)區(qū),這會(huì)導(dǎo)致錯(cuò)誤
功能實(shí)現(xiàn)函數(shù):
char *strcpy(char *dest, const char *src) {char *tmp = dest;while ((*dest++ = *src++) != '\0')/* nothing */;return tmp; }例如:
char str1[30];
char str2[ ] = "hello";
char *pts1 = str1;
char *pts2 = str2;
pts1 = pts2 (錯(cuò)誤)
strcpy (pts1, pts2); (正確)
因?yàn)閜ts1和pts2都是指向字符串的指針,上面的表達(dá)式只復(fù)制字符串的地址而不是字符串本身。
字符串之間的復(fù)制應(yīng)使用strcpy ()函數(shù),它在字符串運(yùn)算中的作用等價(jià)于賦值運(yùn)算符。
?
總之,strcpy()接受兩個(gè)字符串指針參數(shù)。指向最初字符串的第二個(gè)指針可以是一個(gè)已聲明的指針、數(shù)組名或字符串常量。指向復(fù)制字符串的第一個(gè)指針應(yīng)指向空間大到足夠容納該字符串的數(shù)據(jù)對象,比如一個(gè)數(shù)組。記住,聲明一個(gè)數(shù)組將為數(shù)據(jù)分配存儲(chǔ)空間,而聲明一個(gè)指針只為一個(gè)地方分配存儲(chǔ)空間。
?
#include <stdio.h> #include <string.h> #define WORDS "best" #define SIZE 40int main (void) {char *orig = WORDS;char copy[SIZE] = "Be the best that you can be.";char *ps;puts (orig);puts (copy);ps = strcpy (copy + 7 , orig);puts (copy);puts (ps);return 0; } 輸出結(jié)果: best Be the best that you can be. Be the best best上述例子,運(yùn)用了strcpy()函數(shù)的兩個(gè)屬性。首先,它是char*類型,它返回的是第一個(gè)參數(shù)的值,即一個(gè)字符的地址;其次,第一個(gè)參數(shù)不需要指向數(shù)組的開始,這樣就可以只復(fù)制數(shù)組的一部分。
?
7、strncpy()函數(shù)
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
函數(shù)功能:把一個(gè)字符串復(fù)制到另外一個(gè)字符數(shù)組里
功能實(shí)現(xiàn)函數(shù):
har *strncpy(char *dest, const char *src, size_t count) {char *tmp = dest;while (count) {if ((*tmp = *src) != 0)src++;tmp++;count--;}return dest; }上面有講,strcpy()函數(shù)的缺點(diǎn),就是不能檢查目標(biāo)字符串是否容納得下源字符串。使用strncpy()函數(shù),它的第三個(gè)參數(shù)可指明最大可復(fù)制的字符數(shù)。
?
#include <stdio.h> #include <string.h> int main() {char src[40];char dest[12];memset(dest, '\0', sizeof(dest));strcpy(src, "This is w3cschool.cc");strncpy(dest, src, 10);printf("最終的目標(biāo)字符串: %s\n", dest);return(0); } 輸出結(jié)果: 最終的目標(biāo)字符串: This is w38、strstr()函數(shù)
#include <string.h>
char *strstr(const char *haystack, const char *needle);
函數(shù)功能:在一個(gè)字符串中查找另外一個(gè)字符串所在位置
功能實(shí)現(xiàn)函數(shù):
char *strstr(const char *s1, const char *s2) {size_t l1, l2;l2 = strlen(s2);if (!l2)return (char *)s1;l1 = strlen(s1);while (l1 >= l2) {l1--;if (!memcmp(s1, s2, l2))return (char *)s1;s1++;}return NULL; }例如:
#include <stdio.h> #include <string.h> int main() {const char haystack[20] = "W3CSchool";const char needle[10] = "3";char *ret;ret = strstr(haystack, needle);printf("子字符串是: %s\n", ret);return(0); } 輸出結(jié)果: 子字符串是: 3CSchool如果needle字符串不是haystack的一部分,則會(huì)出現(xiàn)警告:
assignment discards ‘const’ qualifier from pointer target type
?
9、memset()函數(shù)
#include <string.h>
void *memset(void *s, int c, size_t n);
函數(shù)功能:可以把字符數(shù)組中所有的字符存儲(chǔ)區(qū)填充同一個(gè)字符數(shù)據(jù)
功能實(shí)現(xiàn)函數(shù):
void *memset(void *s, int c, size_t count) {char *xs = s;while (count--)*xs++ = c;return s; }舉例:
#include <stdio.h> #include <string.h> int main () {char str[50];strcpy(str,"This is string.h library function");puts(str);memset(str,'$',7);puts(str);return(0); } 輸出結(jié)果: This is string.h library function $$$$$$$ string.h library function10、sprintf()函數(shù)
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
函數(shù)功能:按照格式把數(shù)據(jù)打印在字符數(shù)組中,形成一個(gè)字符串
注意:使用sprintf()和使用printf()的方法一樣,只是結(jié)果字符串被存放在數(shù)組fornal中,而不是被顯示在屏幕上。
再有如果想將2轉(zhuǎn)化為字符串“02”,該怎么辦呢?
?
?
11、memcpy函數(shù)
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
函數(shù)功能:從存儲(chǔ)區(qū)src 復(fù)制 n 個(gè)字符到存儲(chǔ)區(qū)dest。
參數(shù):
dest -- 指向用于存儲(chǔ)復(fù)制內(nèi)容的目標(biāo)數(shù)組,類型強(qiáng)制轉(zhuǎn)換為 void* 指針。
src ? -- 指向要復(fù)制的數(shù)據(jù)源,類型強(qiáng)制轉(zhuǎn)換為 void* 指針。
n ? ? ?-- 要被復(fù)制的字節(jié)數(shù)。
返回值:該函數(shù)返回一個(gè)指向目標(biāo)存儲(chǔ)區(qū) dest 的指針。
功能實(shí)現(xiàn)函數(shù):
void *memcpy(void *dest, const void *src, size_t count) {char *tmp = dest;const char *s = src;while (count--)*tmp++ = *s++;return dest; } //示例一 #include <stdio.h> #include <string.h>int main () {const char src[50] = "hello world!";char dest[50];printf("Before memcpy dest = %s\n", dest);memcpy(dest, src, strlen(src)+1);printf("After memcpy dest = %s\n", dest);return(0); } 輸出結(jié)果: Before memcpy dest = After memcpy dest = hello world! //示例二 #include <stdio.h> #include <string.h>int main () {const int src[50] = {1, 2, 3, 4, 5, 6, 7, 8, 9};int dest[50];memcpy(dest, src, 9*4);int i;for (i = 0; i < 9 ; i++){printf ("%d ", dest[i]);}printf ("\n");return(0); } 輸出結(jié)果: 1 2 3 4 5 6 7 8 9strcpy 和 memcpy 的區(qū)別:
(1)strcpy 和 memcpy 都是標(biāo)準(zhǔn) C 庫函數(shù)
(2)strcpy 提供了字符串的復(fù)制。即 strcpy 只用于字符串復(fù)制,并且它不僅復(fù)制字符串內(nèi)容之外,還會(huì)復(fù)制字符串的結(jié)束符。
(3)strcpy函數(shù)的原型是:char* strcpy(char* dest, const char* src);
(4)memcpy提供了一般內(nèi)存的復(fù)制。即memcpy對于需要復(fù)制的內(nèi)容沒有限制,因此用途更廣。
(5)memcpy函數(shù)的原型是:void *memcpy( void *dest, const void *src, size_t count );
?
strcpy 和 memcpy 主要有以下3方面的區(qū)別:
(1)復(fù)制的內(nèi)容不同。strcpy 只能復(fù)制字符串,而memcpy可以復(fù)制任何內(nèi)容,例如字符串?dāng)?shù)組、整型、結(jié)構(gòu)體、類等。
(2)復(fù)制的方法不同。strcpy不需要指定長度,它遇到被復(fù)制字符串結(jié)束符'\0'才結(jié)束,所以容易溢出。memcpy則是根據(jù)其第3個(gè)參數(shù)決定復(fù)制的長度。
(3)用途不同。通常在復(fù)制字符串時(shí)用strcpy,而需要復(fù)制其他類型數(shù)據(jù)時(shí)則一般用memcpy。
?
12、memcmp函數(shù)
?#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
函數(shù)功能:
把存儲(chǔ)區(qū) str1 和存儲(chǔ)區(qū) str2 的前 n 個(gè)字節(jié)進(jìn)行比較。
參數(shù):
str1 -- 指向內(nèi)存塊的指針。
str2 -- 指向內(nèi)存塊的指針。
n -- 要被比較的字節(jié)數(shù)。
返回值:
如果返回值 < 0,則表示 str1 小于 str2。
如果返回值 > 0,則表示 str2 小于 str1。
如果返回值 = 0,則表示 str1 等于 str2。
示例:
#include <stdio.h> #include <string.h>int main (void) {int ret = 0;char str1[5] = {'1','2','3','4','5'};char str2[5] = {'1','A','B','4','5'};ret = memcmp (str1, str2, 5);if(ret > 0){printf("str2 灝忎簬 str1\n");}else if(ret < 0) {printf("str1 灝忎簬 str2\n");}else {printf("str1 絳変簬 str2\n");}return 0; }輸出結(jié)果: str1 小于 str2?
三、將字符串轉(zhuǎn)換成數(shù)字
atoi()函數(shù)、atol()函數(shù)、atof()函數(shù)
#include <stdlib.h>
int atoi(const char *nptr);
long atol(const char *nptr);
double atof(const char *nptr);
函數(shù)功能: 分別把數(shù)字的字符串表示轉(zhuǎn)換為 int、long和double形式。如果沒有執(zhí)行有效的轉(zhuǎn)換返回0.
atoi()功能實(shí)現(xiàn)函數(shù):
int my_atoi(const char *str) {int value = 0;int flag = 1; //判斷符號(hào)while (*str == ' ') ?//跳過字符串前面的空格{str++;}if (*str == '-') ?//第一個(gè)字符若是‘-’,說明可能是負(fù)數(shù){flag = 0;str++;}else if (*str == '+') //第一個(gè)字符若是‘+’,說明可能是正數(shù){flag = 1;str++;}//第一個(gè)字符若不是‘+’‘-’也不是數(shù)字字符,直接返回0else if (*str >= '9' || *str <= '0')?{return 0; ? ?}//當(dāng)遇到非數(shù)字字符或遇到‘\0’時(shí),結(jié)束轉(zhuǎn)化while (*str != '\0' && *str <= '9' && *str >= '0'){value = value * 10 + *str - '0'; //將數(shù)字字符轉(zhuǎn)為對應(yīng)的整形數(shù)str++;}if (flag == 0) //負(fù)數(shù)的情況{value = -value;}return value; }測試:
#include <stdio.h> int my_atoi(const char *str) {int value = 0;int flag = 1; //判斷符號(hào)while (*str == ' ') ?//跳過字符串前面的空格{str++;}if (*str == '-') ?//第一個(gè)字符若是‘-’,說明可能是負(fù)數(shù){flag = 0;str++;}else if (*str == '+') //第一個(gè)字符若是‘+’,說明可能是正數(shù){flag = 1;str++;}//第一個(gè)字符若不是‘+’‘-’也不是數(shù)字字符,直接返回0else if (*str >= '9' || *str <= '0')?{return 0; ? ?}//當(dāng)遇到非數(shù)字字符或遇到‘\0’時(shí),結(jié)束轉(zhuǎn)化while ((*str != '\0')&& (*str <= '9') && (*str >= '0')){value = value * 10 + *str - '0'; //將數(shù)字字符轉(zhuǎn)為對應(yīng)的整形數(shù)str++;}if (flag == 0) //負(fù)數(shù)的情況{value = -value;}return value; }int main(void) {int i ?= my_atoi(" -1234dd");printf("%d\n", i);return 0; } 輸出結(jié)果: -1234測試:
#include <stdio.h> #include <stdlib.h> int main (void) {int val1, val2;long val3, val4;double val5, val6;val1 = atoi ("512you");val2 = atoi ("you512");val3 = atol ("1000000you");val4 = atol ("you1000000");val5 = atof ("3.14you");val6 = atof ("you3.14");printf ("val1 = %d\n", val1);printf ("val2 = %d\n", val2);printf ("val3 = %lu\n", val3);printf ("val4 = %lu\n", val4);printf ("val5 = %lg\n", val5);printf ("val6 = %lg\n", val6);return 0; } 輸出結(jié)果: val1 = 512 val2 = 0 val3 = 1000000 val4 = 0 val5 = 3.14 val6 = 0itoa函數(shù)功能實(shí)現(xiàn):
?
void itoa(int num,char str[] ) { int sign = num,i = 0,j = 0; char temp[11]; if(sign<0)//判斷是否是一個(gè)負(fù)數(shù) { num = -num; }; do { temp[i] = num%10+'0'; ? ? ? ? num/=10; i++; }while(num>0); if(sign<0) { temp[i++] = '-';//對于負(fù)數(shù),要加以負(fù)號(hào) } temp[i] = '\0'; i--; while(i>=0)//反向操作 { str[j] = temp[i]; j++; i--; } str[j] = '\0'; }測試:
#include <stdio.h> void my_itoa(int num,char str[] ) { int sign = num,i = 0,j = 0; char temp[11]; if(sign<0)//判斷是否是一個(gè)負(fù)數(shù) { num = -num; }; do { temp[i] = num%10+'0'; num/=10; i++; }while(num>0); if(sign<0) { temp[i++] = '-';//對于負(fù)數(shù),要加以負(fù)號(hào) } temp[i] = '\0'; i--; while(i>=0)//反向操作 { str[j] = temp[i]; j++; i--; } str[j] = '\0'; }int main (void) {char arr[10]= {0};my_itoa (-123,arr);printf ("%s\n", arr);} 輸出結(jié)果: -123四、字符轉(zhuǎn)十六進(jìn)制
void StrToHex(char *pbDest, char *pbSrc, int nLen) {char h1,h2;char s1,s2;int i;for (i=0; i<nLen/2; i++){h1 = pbSrc[2*i];h2 = pbSrc[2*i+1];s1 = toupper(h1) - 0x30;if (s1 > 9)s1 -= 7;s2 = toupper(h2) - 0x30;if (s2 > 9)s2 -= 7;pbDest[i] = s1*16 + s2;} }總結(jié)
以上是生活随笔為你收集整理的C语言再学习 -- 字符串和字符串函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决git@github.com: Pe
- 下一篇: 大数据统计学直观图表(二)