程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C說話中sscanf()函數的字符串格局化用法

C說話中sscanf()函數的字符串格局化用法

編輯:關於C++

C說話中sscanf()函數的字符串格局化用法。本站提示廣大學習愛好者:(C說話中sscanf()函數的字符串格局化用法)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話中sscanf()函數的字符串格局化用法正文


引見

     sscanf()為C說話尺度庫函數,用於從指定字符串中讀入與指定格局符合的數據。函數原型聲明在stdio.h頭文件中:

int sscanf(const char *str, const char *format, ...);

     該函數依據參數format(格局化字符串)來轉換參數str指向的字符串,轉換後的成果存於對應的可變參數內。其前往值為依照指定格局轉換符勝利讀入且賦值的可變參數數量(若產生婚配毛病而部門勝利,該數量會小於指定的參數數量,乃至為0)。若初次勝利轉換或毛病婚配產生前輸出已停止(如str為空字符串),則前往EOF。產生讀取毛病時也前往EOF,且設置毛病碼errno(如format為空指針時前往EOF並設置errno為EINVAL)。可見,經由過程比擬該函數的前往值與指定的可變參數數量,可斷定格局轉換能否勝利。

     format可為一個或多個{%[*] [width] [{h | l | L}]type | ' ' | '\t' | '\n' | 非%符號}格局轉換符。聚集中{a|b|c}表現格局符a、b、c任選其一。以中括號括起來的格局符可選。%與type為必選,一切格局符必需以%開首。 

 以下扼要解釋各格局符的寄義:

     1) 賦值克制符'*'注解依照隨後的轉換符指導來讀取輸出,但將其拋棄不予賦值(“跳過”)。克制符無需響應的指針可變參數,該轉換也不計入函數前往的勝利賦值次數。%*[width] [{h | l | L}]type 表現知足該前提的字符被過濾失落,不會向目的參數中賦值。

     2) width表現最年夜讀取寬度。當讀入字符數跨越該值,或碰到不婚配的字符時,停滯讀取。多半轉換拋棄肇端的空白字符。這些被拋棄的字符及轉換成果添加的空停止符('\0')均不計入最年夜讀取寬度。

     3) {h | l | L}為類型潤飾符。h指導輸出的數字數值以short intunsigned short int類型存儲;hh指導輸出以signed charunsigned char類型存儲。l(小寫L)指導輸出以long intunsigned long intdouble類型存儲,若與%c或%s聯合則指導輸出以寬字符或寬字符串存儲;ll同等L。L指導輸出以long long類型存儲。

     4) type 為類型轉換符,如%s、%d。

另外,還有兩種特別的格局符:

     1) []:字符聚集。[]表現指定的字符聚集婚配非空的字符序列;^則表現過濾。該操作不會跳過空白字符(空格、制表或換行符),是以可用於目的字符串不以空白字符分隔時。[]內可有一到多個非^字符(含連字符'-'),且無次序請求。%[a-z]表現婚配a到z之間的隨意率性字符,%[aB-]婚配a、B、-中的任一字符;%[^a]則婚配非a的隨意率性字符,即獲得第一個a之前的(不為a的)一切字符。^可感化於多個前提,如^a-z=表現^a-z且^=(既非小寫字母亦非等號)。空字符集%[]和%[^]會招致弗成預知的成果。

     應用[]時吸收輸出的參數必需是有足夠存儲空間的char、signed charunsigned char數組。[]也是轉換符,故%[]後無s。

   %[^]的寄義和用法與正則表達式雷同,故sscanf函數某種水平上供給了簡略的正則表達式功效。

     2) n:至此已讀入值(未必賦值)的等價字符數,該數量必需以int類型存儲。如"10,22"經由"%d%*[^0-9]%n"格局轉換後,%n對應的參數值為3(固然','未介入賦值)。

     'n'並不是轉換符,雖然它可用'*'克制。C尺度宣稱,履行%n指令其實不增長函數前往的賦值次數;但其刊誤表中的描寫與之抵觸。建議不要假定%n對前往值的影響。

 

下表羅列sscanf函數罕見的格局化用法:

另外,還有以下幾種用法:

    【例1】讀入一行字符串

     因字符串能夠含空白字符,故不克不及直接應用%s;而gets函數存在溢出風險,不推舉應用。此時,可以使用sscanf函數,格局化字符串設為"%[^\n]%*c"。%*c用於跳過換行符\n,以便再次讀入下一行。

    【例2】提取"Name = Yuan"中的"Name"

     若行首有空白字符,可用"%*[ \t]%[^= \t]"格局串;

     若不肯定行首有沒有空白字符,可先跳過空白字符:

char szName[] = "Name  =  Yuan";
char szResBuf[32] = {0};
sscanf(szName+strspn(szName," \t"), "%[^= \t]", szResBuf);

    【例3】分化URL

     通俗完成以下所示:

/*****************************************************************************
 * 函數稱號:OaSplitPwFarEndIpInfo
 * 功效描寫:將遠端IP信息分化為目標IP地址和端標語
 * 留意事項:遠端IP信息應形如'udp://192.168.100.221:5000'
*****************************************************************************/
static FUNC_STATUS OaSplitPwFarEndIpInfo(INT8U *pucFarEndIpInfo, INT32U *dwDstUdpPort, INT8U *pucDstIpAddr)
{
  FUNC_STATUS retCode = S_OK;
  INT8U strUdpHead[] = "udp://";
  INT8U ucUdpUrlLen = strlen(strUdpHead);
  INT8U ucIndex = 0;

  CHECK_TRIPLE_POINTER(pucFarEndIpInfo, dwDstUdpPort, pucDstIpAddr, S_NULL_POINTER);

  if(strncasecmp(pucFarEndIpInfo, strUdpHead, ucUdpUrlLen) != 0)
  {
    OmciLog(LOG_CES,"[%s]Cannot Parse FarEndIpInfo(%s)!\n\r", __FUNCTION__, pucFarEndIpInfo);
    return S_ERROR;
  }

  INT8U ucMaxUrlLen = ucUdpUrlLen + STR_IPV4_MAX_LEN; //防止未設置裝備擺設端口時墮入逝世輪回(infinite loop)
  for(ucIndex = 0; (pucFarEndIpInfo[ucUdpUrlLen] != ':') && (ucUdpUrlLen < ucMaxUrlLen); ucIndex++)
  {
    pucDstIpAddr[ucIndex] = pucFarEndIpInfo[ucUdpUrlLen++];
  }
  pucDstIpAddr[ucIndex] = '\0';

  *dwDstUdpPort = strtoul(&pucFarEndIpInfo[ucUdpUrlLen+1], NULL, 10);

  return retCode;
}

     應用sscanf格局化則更加簡略:

char szUrl[] = "udp://192.168.100.221:5000";
char szProt[4] = {0}, szIp[32] = {0};
unsigned int dwPort = 0;
sscanf(szUrl, "%[^://]%*c%*c%*c%[^:]%*c%d", szProt, szIp, &dwPort);
printf("szProt=%s, szIp=%s, dwPort=%d\n", szProt, szIp, dwPort);

    【例4】提取數字

char szDig[]="10,22m,Z86,,880;555:666."; 
int dwIdx = 0, dwVal = 0, dwSize = 0;
while(1 == sscanf(szDig+dwIdx, "%d%*[^0-9]%n", &dwVal, &dwSize))
{
  dwIdx += dwSize;
  printf("dwIdx=%d, dwSize=%d, dwVal=%d\n", dwIdx, dwSize, dwVal); 
}

     上述完成略加改革,便可用於處置某種字符分隔的數字串。

總結 

     綜上,關於簡略的字符串剖析,采取sscanf函數處置比擬簡練。若字符串比擬龐雜,則可借助響應的正則表達式庫。須要留意,sscanf格局化的目標是“截取”,而正則表達式的目標是“婚配”,不克不及完整同等。

     以上就是本文的全體內容改了,願望對年夜家的進修能有所贊助,假如疑問的話迎接年夜家留言評論辯論。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved