C语言库函数相关
計算機考研機試筆記之C/C++基礎2
- C語言庫函數
- stdio.h
- stdlib.h
- string.h
- math.h
參考書籍:
計算機考研復試上機指導全書.天勤計算機考研系列.孫肇博 張飛飛.2014.01
C語言庫函數
stdio.h
從已知字符串buffer中獲取與指定格式相符的數據,函數原型如下:int sscanf(const char *buffer, const char *format, ...); 示例:#include <stdio.h> int main() {char buf[] = "2019,w:c:b";int a;char b,c,d;sscanf(buf,"%d,%c:%c:%c",&a,&b,&c,&d);printf("%d_%c_%c_%c",a,b,c,d); return 0; } 輸出結果:2019_w_c_b 此函數可以用來將字符串類型表示的數據,轉換為其他類型。
將數據按照一定格式寫入字符串,函數原型如下:int sprintf(char *buffer, const char *format, ...); 示例:
計算已知的兩小數之和,并將結果的第一位小數輸出#include <stdio.h> int main() {char buf[10];double a = 1.23456, b = 1.23456;sprintf(buf,"%f",a+b);int i = 0;while(buf[i++] != '.');printf("%s\n",buf);printf("%c",buf[i]);return 0; } 輸出結果:2.469120 4 此函數中的buffer,包含”\0“,因此在設置數組時,數組長度要加一。
把字符 char(一個無符號字符)推入到指定的流 stream 中,使它成為下一個被讀取到的字符。函數原型如下:int ungetc(int char, FILE *stream); 示例:#include <stdio.h> int main() {char ch;int num;while((ch = getchar()) != '\n'){if(ch == ' ')//過濾空格continue;ungetc(ch,stdin);//將獲取的字符ch退回到stdin流 scanf("%d",&num);//從stdin中讀取數據,以int類型存入num變量 printf("_%d_ ",num);}return 0; } 輸出結果:20 15 14 17 _20_ _15_ _14_ _17_ 該函數的作用,我比較認同以下這個說法:
當從流中讀出字符,但不是所需內容時,為了不改流的內容,需要回寫入流中。寫回后再讀,仍會讀出來。1
注意:
ungetc 不能連續多次調用。兩次 ungetc 調用之間必須至少有一次讀操作或者文件指針移動操作(fseek,rewind 等 ) ,ungetc 只影響輸入流,而不影響與輸入流關聯的外存文件。
用于重定向輸入輸出流。該函數可以在不改變代碼原貌的情況下改變輸入輸出環境,但使用時應當保證流是可靠的。函數原型如下:FILE *freopen(const char *fname, const char *mode, FILE *stream); 示例:#include <stdio.h> int main() {freopen("in.txt","r",stdin);//輸入重定向,輸入數據將從當前目錄下的in.txt文件中讀取 char ch;while((ch = getchar()) != EOF){printf("%c",ch);}fclose(stdin);//關閉重定向輸入return 0; } in.txt文件內容:
輸出結果:123456wertyui
stdlib.h
把用字符串表示的浮點數(或整數)轉換為double型的數據。函數原型如下:double atof(const char *str); 示例:#include <stdio.h> #include <stdlib.h> int main() {char *str1 = "11.62";char *str2 = "-11.62";char *str3 = "11.62e-2";char *str4 = "11.62abc1.26";char *str5 = "a11.62";double a,b,c,d,e;a = atof(str1);b = atof(str2);c = atof(str3);d = atof(str4);e = atof(str5);printf("%lf\n%lf\n%lf\n%lf\n%lf",a,b,c,d,e); return 0; } 輸出結果:11.620000 -11.620000 0.116200 11.620000 0.000000 注意:待轉換的字符串必須是有效的整數或浮點數(正負均可)開頭才能轉換成功。上例中str5不是以有效數字開頭,因此無法轉換。
malloc()申請系統內存空間,申請成功返回新開辟內存空間的首地址,申請失敗返回NULL。
free()釋放內存空間。二者函數原型如下:void *malloc(size_t size); void free(void *ptr); 示例:#include <stdio.h> #include <stdlib.h> int main() {struct sqlist{int data;struct sqlist *next;};sqlist *p;p = (sqlist *)malloc(sizeof(sqlist));//對返回值一定要進行強制類型轉換,函數參數為申請的內存空間大小//做一些操作……free(p);return 0; }
快速排序,后面提及排序時具體講解。
string.h
strlen()
獲取字符串長度,不包括”\0“。
示例:
#include <stdio.h> #include <string.h> int main() {char c[] = "welcome";printf("%d",strlen(c));return 0; }輸出結果:
7注:strlen()是一個函數,需要進行函數調用;而sizeof()是單目運算符,在編譯時計算緩沖區的長度,因此 sizeof ()不能用來返回動態分配的內存空間的大小。
實現strlen()函數功能:見”C語言:三種方法模擬實現strlen函數“2
strcmp()
從左往右比較str1和str2兩個字符串對應位置的ASCII碼值的大小。當值不同時,或遇到結束符時,返回結果。當str1 < str2時,返回負數;當str1 = str2時,返回0;當str1 > str2時,返回正數。只能用于字符串的比較,不能用于各種類型的數組比較,函數原型如下:
示例:
#include <stdio.h> #include <string.h> int main() {char *a = "acm";char *b = "block";char *c = "code";printf("%d\n",strcmp(c,b)); printf("%d\n",strcmp(a,a));printf("%d",strcmp(a,c)); return 0; }輸出結果:
1 0 -1一種實現strcmp()函數功能的函數:
#include <stdio.h> int strcmp_self(const char *str1, const char *str2){//函數傳入參數為const char* ,屬于有符號數 while(*str1 && *str2 && (*str1 == *str2)){str1++;str2++;}if(*(unsigned char *)str1 > *(unsigned char *)str2)//由于該函數參數為有符號數,但字符串的ASCII碼無負值//若不轉換,比較的時候會出現錯誤 //因此要使用unsigned char*強制轉換為無符號數 return 1;else if(*(unsigned char *)str1 < *(unsigned char *)str2)return -1;elsereturn 0; } int main() {char *a = "acm";char *b = "block";char *c = "code";printf("%d\n",strcmp_self(c,b)); printf("%d\n",strcmp_self(a,a));printf("%d",strcmp_self(a,c)); return 0;return 0; }運行結果同上。
strcpy()
將以from為首地址的字符串連同’\0’,復制到以to為首地址的存儲空間,只能拷貝字符串,不能用于各種類型的數組復制,原型如下:
函數實現:
#include <stdio.h> #include <assert.h> char *strcpy_self(char *to, const char *from){assert((to != NULL) && (from != NULL));char *ret = to;while((*ret++ = *from++) != '\0');return to; } int main() {char a[6] = "good";char b[6] = "bad";//此處未使用指針形式,大家也請注意//通過char *指針修改字符串常量中的字符會導致Segment fault錯誤//原因是char *a = "good",good的存儲位置是只讀的內存地址//不允許執行以下的strcpy()操作printf("%s\t%s\n",a,b);strcpy_self(a,b);printf("%s\t%s\t",a,b);return 0; }輸出結果:
good bad bad bad與strcpy()相似的有一個strncpy()的函數,該函數功能類似,只不過strncpy拷貝的是字符,最后一個’\0’沒有拷貝,所以拷貝的時候需要對串進行清零處理,在最后加‘\0’,一定要養成好習慣。同時,使用strncpy()時,一定要防止內存重疊。其實現如下,將以src為首地址的字符串中的前n個字符拷貝到dest所指的數組中,并返回數組首地址:
#include <stdio.h> #include <assert.h> char *strncpy_self(char *dest,const char *src,int n) {assert((dest!=NULL)&&(src!=NULL));char *cp=dest;while(n&&(*cp++=*src++)!='\0'){n--;}if(n){while(--n)*cp++='\0';}return dest; } int main() {char a[6] = "good";char b[6] = "bad";printf("%s\t%s\n",a,b);strncpy_self(a,b,2);printf("%s\t%s\t",a,b);return 0; }strcat()
將以str2為首地址的字符串(包括’\0’)追加到以str1為首地址的字符串后面(刪除*str1后面的’\0’),其函數原型如下:
我一般不使用strcat(),容易把自己搞糊涂,弄不清楚字符串內容最終成為了什么,或者造成內存溢出等錯誤,故習慣直接在主函數中寫一遍:
#include <cstdio> int main() {char a[15] = "good";char b[15] = "bad";printf("%s\t%s\n",a,b);//函數實現將字符數組 b 的內容追加到字符數組 a//數組 a 一定要足夠大,足以放下追加的內容int i = 0, j = 0;while(a[i++]);i--;while(b[j]){a[i++] = b[j++];}a[i] = '\0';//補充結束符printf("%s\t%s\t",a,b);return 0; }輸出結果:
good bad goodbad bad```strstr()
判斷字符串*str2是否是*str1的子串,返回一個指針,指向字符串*str2在字符串*str1中出現的首位置,否則返回NULL。函數原型如下:
函數實現:
#include <stdio.h> #include <assert.h> const char *strstr_self(const char *str1,const char *str2){const char *p1;const char *p2;if(!str1 || !str2){return NULL;}//遍歷str1字符串while(*str1){//遍歷子串p1 = str1;p2 = str2;do{if(!*p2) //到了str2的結束位置,返回str1的位置return str1;}while(*p1++ == *p2++);str1++;}return NULL; } int main() {char a[15] = "good";char b[15] = "ood";printf("%s\t%s\n",a,b);const char *c = strstr_self(a,b);printf("%s",c);return 0; }strtok()
用*str2中字符將*str1字符串分割,返回指針,指向分割下來的字符串首地址,若無分割下來的字符串,返回NULL。函數原型如下:
示例:
#include <stdio.h> #include <string.h> int main() {char a[] = "see you tomorrow";char b[] = " ";printf("%s\t%s\n",a,b);char *res = NULL;res = strtok(a,b);while(res != NULL){//注意,第一次調用strtok()函數時,第一個參數時str1//但是之后調用時,第一個參數要改為NULL printf("%s\n",res);res = strtok(NULL,b);}return 0; }輸出結果:
see you tomorrow see you tomorrowmemset()
將一段內存置為某個值,**常用!**函數原型為:
示例:
#include <stdio.h> #include <string.h> int main() {char a[] = "see you tomorrow";printf("%s\n",a);memset(a,'b',6); //將字符串數組 a 的前6個字符置為字符'b' printf("%s\n",a);return 0; }輸出結果:
see you tomorrow bbbbbbu tomorrowmath.h
見下篇
https://blog.csdn.net/hubi0952/article/details/6897503 ??
https://blog.csdn.net/windyj809/article/details/80037006 ??
總結
- 上一篇: Java将一张图片放在另一张图片上(位置
- 下一篇: jQuery控制在ready之后执行方法