1. 程式人生 > >【C語言】C語言中格式化字元的具體用法(C語言中%的那些事)

【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位小數位的浮點數並且左對齊。你可以修改帶字母lh%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指向的地址空間

  1. void  reverse_string(char  * string)  
  2. {  
  3.     if (* string ==  '\ 0' )  
  4.         printf(“%c” ,* string);  
  5.     其他  
  6.     {  
  7.         reverse_string(++字串);  //輸出下一個字元  
  8.         printf(“%c” ,*( - string));  //因為字串已經執行完++,所以若要輸出當前字元得-  
  9.     }  
  10. }  
  11. int  main()  
  12. {  
  13.     char  s [] = “abcdefgh” ;  
  14.     reverse_string1(一個或多個);  
  15.     返回 0;  
  16. }
  1. void  reverse_string(char  * string)  
  2. {  
  3.     if (* string ==  '\ 0' )  
  4.         printf(“%c” ,* string);  
  5.     其他  
  6.     {  
  7.         reverse_string(++字串);  //輸出下一個字元  
  8.         printf(“%c” ,*( - string));  //因為字串已經執行完++,所以若要輸出當前字元得-  
  9.     }  
  10. }  
  11. int  main()  
  12. {  
  13.     char  s [] = “abcdefgh” ;  
  14.     reverse_string1(一個或多個);  
  15.     返回 0;  
  16. }