【C語言】C語言中格式化字元的具體用法(C語言中%的那些事)
格式字元格式字元用以指定輸出項的資料型別和輸出格式。
格式字元控制:
說明:的sprintf(格式化後的字元,“%(長度)格式符”,格式化前的字元);
1,d格式符用來輸出十進位制數有以下幾種用法。:
(1),%d按整數的實際長度輸出。
(2),%MD,米為指定的輸出欄位的寬度。如果資料位數小於米,則左端補以空格,若大於米,則按實際位數輸出。(3),%LD,輸出長整型資料。例:long a = 135790; 的printf(“%LD”,A);如果用%d輸出就會發生錯誤,因為整型資料的範圍是-32768到32767。對於長型資料應當用%ld的格式輸出,對長整型資料也可以指定欄位寬度,如:%8LD。
2,O格式符,以八進位制數形式輸出整數。由於記憶體單元中的各位的值(0或1)按八進位制形式輸出,因此輸出的數值不帶符號,即將符號位也一起作為八進位制的一部分輸出。
3,X格式符,以十六進位制數形式輸出整數。同樣不會出現負的十六進位制數。同樣可以用%LX輸出長整型數,也可以指定輸出欄位寬度。
4,U格式符,用來輸出無符號型資料,即無符號數,以十進位制形式輸出。一個有符號整數(int型)也可以用%U格式輸出,反之,一個無符號型的資料也可以用% d格式輸出。按相互賦值的規則處理.Unsigned型資料也可以用%×格式輸出。
5,C格式符,用來輸出一個字元。一個字元型資料也可以用整數形式輸出。
6,S格式符,用來輸出一個字串。
(1),%S,的的printf(“%S”,“HELLO”);
(2),%MS輸出字串佔米列,如字串本身大於米,則突破米的限制,字串全部輸出,如果小於米,則左補空格(3),% - 。毫秒如果字串小於米,則在米範圍內,字串向左靠,右補空格。
(4),%m.ns,輸出佔米列,但只取字串中左端Ñ個字元。這Ñ個字元輸出在米列的右側,左補空格。
(5),% - m.ns,其中M,N含義同上,N個字元輸出在米範圍的左側,右補空格如果N> M,則自動取值,即保證Ñ個字元正常輸出。
7,F格式符,用來輸出實數(包括單,雙精度),以小數形式輸出。
(1),%F,不指定欄位寬度,有系統自動指定,使整數部分全部如數輸出,並輸出6位小數。應當注意,並非全部數字都是有效數字。單精度實數的有效位數一般是7位。
(2),%m.nf指定輸出的資料佔米列,其中有Ñ位小數。如果數值長度小於米,則左補空格。
(3),% - m.nf與%m.nf基本相同,只是輸出的數值向左端靠,右端補空格。
8,電子格式符,以指數形式輸出。
9,克格式符,用來輸出實數,它根據數值的大小,自動選擇˚F格式或ë格式(選擇輸出時佔用寬度較小的一種),並且不輸出無意義的零。
************************************************** *******
碼 | 格式 |
%C | 字元 |
%d | 帶符號整數 |
%一世 | 帶符號整數 |
%E | 科學計數法,使用小寫的“e” |
%E | 科學計數法,使用大寫“E” |
%F | 浮點數 |
%G | 使用%E或%F中較短的一個 |
%G | 使用%E或%F中較短的一個 |
Ø% | 八進位制 |
%S | 一串字元 |
%u | 無符號整數 |
%X | 無符號十六進位制數,用小寫字母 |
%X | 無符號十六進位制數,用大寫字母 |
%p | 一個指標 |
%N | 引數應該英文的一個指向一個整數的指標 指向的的英文字元數放置的位置 |
%% | 一個'%'符號 |
一個位於一個%和格式化命令間的整數擔當著一個最小欄位寬度說明符,並且加上足夠多的空格或0使輸出足夠長。如果你想填充0,在最小欄位寬度說明符前放置0。你可以使用一個精度修飾符,它可以根據使用的格式程式碼而有不同的含義。
- 用%E,%E和%F,精度修飾符讓你指定想要的小數位數。例如,
%12.6f
將會至少顯示12位數字,並帶有6位小數的浮點數。
- 用%克和%G,精度修飾符決定顯示的有效數的位數最大值。
- 用%S,修飾符精度簡單的表示一個最大的最大長度,以補充句點前的最小欄位長度。
所有的printf()的輸出都是右對齊的,除非你在%符號後放置了負號。例如: %-12.4f
將會顯示12位字元,4位小數位的浮點數並且左對齊。你可以修改帶字母l和h%d,%i,%o,%u和%x等型別說明符指定長型和短型資料型別(例如%hd表示一個短整數)。%e,%f和%g型別說明符,可以在它們前面放置l指出跟隨的是一個double。%g,%f和%e型別說明符可以置於字元'#'前保證出現小數點,即使沒有小數位。帶%×型別說明符的'#'字元的使用,表示顯示十六進位制數時應該帶加'0x'字首。帶%氧氣型別說明符的'#'字元的使用,表示顯示八進位制數時應該帶一個'0'字首。
****************************格式化符在sscanf的的函式中的強大用法*********** * *****************
1.常見用法。
char buf [512];
的sscanf(“123456”,“%s”時,BUF); //此處BUF是陣列名,它的意思是將123456以%S的形式存入BUF中!
printf(“%s \ n”,buf);
結果為:123456
2.取指定長度的字串。如在下例中,取最大長度為4位元組的字串。
的sscanf(“123456”,“%4S”,BUF);
printf(“%s \ n”,buf);
結果為:1234
3.取到指定字元為止的字串。如在下例中,取遇到空格為止字串。
sscanf(“123456 abcdedf”,“%[^]”,buf);
printf(“%s \ n”,buf);
結果為:123456
4.僅限包含指定字符集的字串。如在下例中,僅包含1到9和小寫字母的字串。
的sscanf(“123456abcdedfBCDEF”,“%[1-9A-Z]”,BUF);
printf(“%s \ n”,buf);
結果為:123456abcdedf
當輸入:
的sscanf(“123456abcdedfBCDEF”,“%[1-9A-Z]”,BUF);
的printf(“%S \ n”個,BUF);
結果為:123456
5.取到指定字符集為止的字串。如在下例中,取遇大寫字母為止的字串。
sscanf(“123456abcdedfBCDEF”,“%[^ AZ]”,buf);
printf(“%s \ n”,buf);
結果為:123456abcdedf
6,給定一個字串iios / 12DDWDFF @ 122,獲取/和@之間的字串,先將“iios /”過濾掉,再將非'@'的一串內容送到buf中
sscanf(“iios / 12DDWDFF @ 122”,“%* [^ /] /%[^ @]”,buf);
printf(“%s \ n”,buf);
結果為:12DDWDFF
7,給定一個字串“你好,世界”,僅保留世界(注意:“”之後有一空格,%S遇空格停止,加*則是忽略第一個讀到的字串)。
sscanf(“hello,world”,“%* s%s”,buf);
printf(“%s \ n”,buf);
結果為:世界
%* S表示第一個匹配到的%S被過濾掉,即你好被過濾了
如果沒有空格則結果為NULL。
sscanf的的功能很類似於正則表示式,但卻沒有正則表示式強大,所以如果對比較複雜的字串處理,建議使用正則表示式。
// ------------------------------------------------ -------
用它來分隔類似這樣的字串2006:03:18:
int a,b,c;
/ * sscanf(“2006:03:18”,“%d:%d:%d”,a,b,c); * / / *錯誤方法,要在變數a,b,c前加上取地址符,由huanmie_09修改* /
的sscanf(“2006:03:18”,“%d:%d:%d”,&一個,及B,C);
以及2006:03:18 - 2006:04:18:
char sztime1 [16] =“”,sztime2 [16] =“”;
sscanf(“2006:03:18 - 2006:04:18”,“%s - %s”,sztime1,sztime2);
但是後來,我需要處理2006:03:18-2006:04:18
僅僅是取消了' - '兩邊的空格,卻打破了%S對字串的界定。
我需要重新設計一個函式來處理這樣的情況?這並不複雜,但是,為了使所有的程式碼都有統一的風格,我需要改動很多地方,把已有的sscanf的的替換成我自己的分割函式。我以為我肯定需要這樣做,並伴隨著對的的sscanf的強烈不滿而入睡;一覺醒來,發現其實不必。
如果讀取的字串,不是以空格來分隔的話,就可以使用%[]。
%[]類似於一個正則表示式。[AZ]表示讀取AZ的所有字元,[^ AZ]表示讀取除AZ以外的所有字元。
所以那個問題也就迎刃而解了:
sscanf(“2006:03:18 - 2006:04:18”,“%[0-9,:] - %[0-9,:]”,sztime1,sztime2);
在softmse(傑克)的問題貼中,去掉我(去掉我)et / Expert / topic / 4843 / 4843294.xml?temp = .4321558中,給出了一個很cool的sscanf用例,而後通過學習,發現sscanf的真棒,現做一總結。
蒐集一些特殊用法:
%[]的用法:%[]表示要讀入一個字元集合,如果[後面第一個字元是“^”,則表示反意思。
[]內部字串可以是1或更多字元組成。空字符集(%[])是違反規定的,可
導致不可預知的結果。%[^]也是違反規定的。
%[AZ]讀取在AZ之間的字串,如果不在此之前則停止,如
char s [] =“你好,我的朋友”; //注意:,逗號在不AZ之間
sscanf的(S,“%[AZ]”,字串); // string = hello
%[^ az]讀取不在az之間的字串,如果碰到az之間的字元則停止,如
char s [] =“HELLOkitty”; //注意:,逗號在不是AZ之間
sscanf(s,“%[^ az]”,string); // string = HELLO
%* [^ =]前面帶*號表示不儲存變數。跳過符合條件的字串。
char s [] =“notepad = 1.0.0.1001”;
char szfilename [32] =“”;
int i = sscanf(s,“%* [^ =]”,szfilename);
// szfilename = NULL,因為沒儲存
int i = sscanf(s,“%* [^ =] =%s”,szfilename);
// szfilename = 1.0.0.1001
%40C讀取40個字元
%[^ =]讀取字串直到'=','^'後面可以帶更多字元,如:
char s [] =“notepad = 1.0.0.1001”;
char szfilename [32] =“”;
int i = sscanf(s,“%[^ =]”,szfilename);
// szfilename =記事本
如果引數格式是:%[^ =:],那麼也可以從notepad:1.0.0.1001讀取記事本
注意:當碰到不滿足條件的字元後,sscanf的的就會停止執行,不再掃描之後的字元。
******************** strtok的字串分割函式也是個實戰性較強的函式,但是已被strsep函式取代********* * *************
#include <string.h>
char * strtok(char * str1,const char * str2);
函式返回字串STR1中緊接“標記”的部分的指標,字串str2的是作為標記的分隔符。STR1 指向作為標記的分隔符。之後所以的呼叫STR1 都應為NULL。
例如:
char str [] =“now#是所有#好男人來到他們國家的援助之時”;
char delims [] =“#”;
char * result = NULL;
result = strtok(str,delims);
while(result!= NULL){
printf(“結果是\”%s \“\ n”,result);
result = strtok(NULL,delims);
}
以上程式碼的執行結果是:
結果是“現在”
結果是“是所有人的時間”
結果是“好男人來了”
結果是“援助他們的國家”
-------------------------------------------------- -------------------------------
char * strname = NULL;
則strName =(字元*)malloc的(的sizeof(char)的);
memset的(即strName,0,的sizeof(char)的);
的strcpy(則strName,“通|太陽|的java |谷歌”);
char delims [] =“|”;
char * ret = NULL;
RET =(字元*)malloc的(的sizeof(char)的);
memset的的(保留,0,的的sizeof(char)的的);
RET = strtok的(即strName,delims);
while(ret!= NULL)
{
printf(“%s \ n”,ret);
RET =(字元*)malloc的(的sizeof(char)的);
memset的的(保留,0,的的sizeof(char)的的);
RET = strtok的(NULL,delims);
}
-------------------------------------------------- -----------------------------------
strsep
baikeViewInfo = {ID:“2466295”,編輯:“真”,標題:“strsep”,expIndex:“0”};
原型:char * strsep(char ** stringp,const char * delim); 功能:分解字串為一組字串從stringp指向的位置起向後掃描,遇到DELIM指向位置的字元後,將此字元替換為NULL,返回stringp指向的地址。
********************* strncat函式字串擷取接接*********************** * *********
strncat函式函式
baikeViewInfo = {ID:“1028544”,編輯:“真”,標題:“strncat函式”,expIndex:“0”};
原型:extern char * strncat(char * dest,char * src,int n); 用法:#include < string.h > 功能:把SRC所指字串的前字串新增到DEST結尾處(覆蓋DEST結尾處的'\ 0')並新增'\ 0'。 說明:SRC和DEST所指記憶體區域不可以重疊且DEST中必須有足夠的空間來容納SRC的字串。 返回指向DEST的指標。 舉例: // strncat.c #include <syslib.h> #include <string.h> 主要() { char d [20] =“金色全球”; char * s =“檢視WinIDE庫”; clrscr(); strncat函式函式(d,S,5); 的printf(“%S”,d); 的的getchar(); 返回0; }
以上程式碼的執行結果是:
Golden Global View注意檢視前面有個空格字元。
*********************** strncasecmp ************************** *
strncasecmp
baikeViewInfo = {ID:“1589829”,編輯:“真”,標題:“strncasecmp”,expIndex:“0”};
相關函式:BCMP,memcmp,STRCMP,與strcoll,STRNCMP 表頭檔案:#include <string.h> 函式定義:int strncasecmp(const char * s1,const char * s2,size_t n) 函式說明:strncasecmp()用來比較引數S1和S2字串前Ñ個字元,比較時會自動忽略大小寫的差異 返回值:若引數s1和s2字串相同則返回0 s1若大於s2則返回大於0的值s1若小於s2則返回小於0的值 #include <string.h>
char * a =“acddfefekr”;
char * b =“AbCddfefekr”;
的printf(“%d \ n”個,strncasecmp(A,B,2));
以上程式碼的執行結果是:1
****************************** strcasecmp ******************* ******
strcasecmp
(忽略大小寫比較字串)
相關函式BCMP,memcmp,STRCMP,與strcoll,STRNCMP
表頭檔案#include < string.h >
定義函式int strcasecmp(const char * s1,const char * s2);
函式說明strcasecmp()用來比較引數S1和S2字串,比較時會自動忽略大小寫的差異。
此原文這裡有錯誤:返回值若引數S1和S2字串相同則返回0.s1長度大於S2長度則返回大於0的值,S1長度若小於S2長度則返回小於0的值。
strcasecmp是比較兩個字串,但比較的不是它們的長度,而是字元的編碼大小 - 但字母不區分大小寫,如果S1小於S2,返回小於0的一個整數;如果S1等於S2,返回值是0;如果S1> S2,返回一個大於0的整數。
#include <string.h>
主要()
{
char * a =“aBcddfefekr”;
char * b =“AbCddfefekr”;
的printf(“%d \ n”個,strcasecmp(A,B));
}
執行aBcDeF = AbCdEf
以上程式碼的執行結果是:0
注意與strncasecmp()的區別,不要弄混了。
該函式是二進位制安全的,且對大小寫不敏感。
*************************函式strncpy *********************** * *******
strncpy:字元複製原型:char * strncpy(char * dest,char * src, size_t n);
功能:將字串的SRC中最多Ñ個字元複製到字元陣列DEST中(它並不像的strcpy的一樣遇到NULL才停止複製,而是等湊夠Ñ個字元才開始複製),返回指向DEST的指標。
說明:
如果n> dest串長度,dest棧空間溢位產生崩潰異常。
否則:
1)SRC串長度<= DEST串長度,(這裡的串長度包含串尾NULL字元)
如果n =(0,src串長度),src的前n個字元複製到dest中。但是由於沒有NULL字元,所以直接訪問dest串會發生棧溢位的異常情況。
如果n = src串長度,與strcpy一致。
如果n = dest串長度,[0,src串長度]處存放於desk字串,(src串長度,dest串長度]處存放NULL。
2)SRC串長度> DEST串長度
如果N = DEST串長度,則DEST串沒有NULL 字元,導致會輸出會有亂碼。如果不考慮SRC串複製完整性,可以將DEST最後一個字元置為NULL。
綜上,一般情況下,使用函式strncpy()函式時,建議將Ñ置為DEST串長度(除非你將多個SRC串都複製到目標暫存器陣列,並且從DEST尾部反向操作),複製完畢後,為保險起見,將DEST串最後一字元置NULL,避免發生在第2)種情況下的輸出亂碼問題。當然嘍,無論是的strcpy的還是函式strncpy()函式,保證SRC串長度<目的地串長度才是最重要的。
*******************************的snprintf ***************** * *************
的的snprintf
baikeViewInfo = {ID:“1966670”,編輯:“真”,標題:“的snprintf”,expIndex:“0”};
int snprintf(char * str, size_t size,const char * format,...);
將可變個引數(...)按照格式格式化成字串,然後將其複製到海峽中
(1)如果格式化後的字串長度<size,則將此字串全部複製到str中,並給它後新增一個字串結束符('\ 0');
(2)如果格式化後的字串長度> = size,則將其中的(size-1)個字元複製到str中,並給它後新增一個字串結束符('\ 0')
函式返回值:若成功則返回欲寫入的字串長度,若出錯則返回負值.--------------------------- -----------------
int snprintf(char * restrict buf,size_t n,const char * restrict format,...);
函式說明:最多從源串中拷貝N-1個字元到目標串中,然後再在後面加一個0所以如果目標串的大小為Ñ
的話,將不會溢位。
函式返回值:若成功則返回欲寫入的字串長度,若出錯則返回負值。
結果1(推薦的用法)
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str [10] = {0,};
的snprintf(STR,的sizeof(STR),“0123456789012345678”);
printf(“str =%s \ n”,str);
返回0;
}
#include <stdio.h> // snprintf()
#include < string.h > // strlen()
int main()
{
char toname [30];
char * name =“yangtaiping”;
printf(“strlen(name)=%d \ n”,strlen(name));
的snprintf(toname,的sizeof(toname),“姓名:%S”,姓名);
printf(“toname =%s \ n”,toname);
printf(“strlen(name)=%d \ n”,strlen(name));
}
的strcpy()的sprintf()的strcat()存在安全隱患,其對應的安全版本為:函式strncpy()的snprintf()strncat函式()。
snprintf(s,100,“%。* S”,3,“abcd”); s的值為abc%。* s表示有兩項,第一項指定了長度,第二項則是%s的內容,所以取前三位詞條圖冊更多圖冊
類似的函式還有:
#include <stdio.h>
int printf(const char * format,...); //格式化輸出到標準輸出裝置
int fprintf(FILE * stream,const char * format,...); //格式化輸出到檔案流
int sprintf(char * str,const char * format,...); //格式化的輸出字串輸出到STR指向的地址空間
- void reverse_string(char * string)
- {
- if (* string == '\ 0' )
- printf(“%c” ,* string);
- 其他
- {
- reverse_string(++字串); //輸出下一個字元
- printf(“%c” ,*( - string)); //因為字串已經執行完++,所以若要輸出當前字元得-
- }
- }
- int main()
- {
- char s [] = “abcdefgh” ;
- reverse_string1(一個或多個);
- 返回 0;
- }
- void reverse_string(char * string)
- {
- if (* string == '\ 0' )
- printf(“%c” ,* string);
- 其他
- {
- reverse_string(++字串); //輸出下一個字元
- printf(“%c” ,*( - string)); //因為字串已經執行完++,所以若要輸出當前字元得-
- }
- }
- int main()
- {
- char s [] = “abcdefgh” ;
- reverse_string1(一個或多個);
- 返回 0;
- }