日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sscanf,sscanf_s及其相关用法(字符串格式化为其他类型)

發(fā)布時(shí)間:2024/4/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sscanf,sscanf_s及其相关用法(字符串格式化为其他类型) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

#include<stdio.h>

?定義函數(shù) int sscanf (const char *str,const char * format,........);

函數(shù)說明?
?sscanf()會(huì)將參數(shù)str的字符串根據(jù)參數(shù)format字符串來轉(zhuǎn)換并格式化數(shù)據(jù)。格式轉(zhuǎn)換形式請參考scanf()。轉(zhuǎn)換后的結(jié)果存于對應(yīng)的參數(shù)內(nèi)。

返回值 成功則返回參數(shù)數(shù)目,失敗則返回-1,錯(cuò)誤原因存于errno中。 返回0表示失敗??? 否則,表示正確格式化數(shù)據(jù)的個(gè)數(shù)??? 例如:sscanf(str,"%d%d%s", &i,&i2, &s);??? 如果三個(gè)變成都讀入成功會(huì)返回3。??? 如果只讀入了第一個(gè)整數(shù)到i則會(huì)返回1。證明無法從str讀入第二個(gè)整數(shù)。

? ? ? ? ? ? main()?
??????????? {?
??????????? int i;?
??????????? unsigned int j;?
??????????? char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”;?
??????????? char s[5];?
??????????? sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s);?
??????????? printf(“%d %d %s ”,i,j,s);?
??????????? }

? ? ? ? ? ? 執(zhí)行 10 27 aaaaa

大家都知道sscanf是一個(gè)很好用的函數(shù),利用它可以從字符串中取出整數(shù)、浮點(diǎn)數(shù)和字符串等等。它的使用方法簡單,特別對于整數(shù)和浮點(diǎn)數(shù)來說。但新手可能并不知道處理字符串時(shí)的一些高級用法,這里做個(gè)簡要說明吧。

  1. 常見用法。

  charstr[512]={0};
  sscanf("123456","%s",str);
  printf("str=%s",str);

  2. 取指定長度的字符串。如在下例中,取最大長度為4字節(jié)的字符串。

  sscanf("123456","%4s",str);
  printf("str=%s",str);

  3. 取到指定字符為止的字符串。如在下例中,取遇到空格為止字符串。

  sscanf("123456abcdedf","%[^]",str);
  printf("str=%s",str);

 4. 取僅包含指定字符集的字符串。如在下例中,取僅包含1到9和小寫字母的字符串。

  sscanf("123456abcdedfBCDEF","%[1-9a-z]",str);
  printf("str=%s",str);

  5. 取到指定字符集為止的字符串。如在下例中,取遇到大寫字母為止的字符串。

  sscanf("123456abcdedfBCDEF","%[^A-Z]",str);
  printf("str=%s",str);

/

可以用如下代碼將字符串形式的ip地址轉(zhuǎn)換為四個(gè)整數(shù):

  • char?*?inputIp??
  • int?ip[4];??
  • sscanf_s(inputIp,?"%d.%d.%d.%d",?&ip[0],?&ip[1],&ip[2],&ip[3]);??
  • ????? 注意sscanf_s,當(dāng)讀入的類型是整數(shù)或其它長度可以確定的類型時(shí),不能在類型后面跟上長度,但是對于字符串類型(char *)長度無法得知?jiǎng)t必須在類型后面明確指出字符串的最大長度(即可以容納的空間)。舉例如下:

  • //?crt_sscanf_s.c??
  • //?This?program?uses?sscanf_s?to?read?data?items??
  • //?from?a?string?named?tokenstring,?then?displays?them.??
  • ??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • ??
  • int?main(?void?)??
  • {??
  • ???char??tokenstring[]?=?"15?12?14...";??
  • ???char??s[81];??
  • ???char??c;??
  • ???int???i;??
  • ???float?fp;??
  • ??
  • ???//?Input?various?data?from?tokenstring:??
  • ???//?max?80?character?string?plus?NULL?terminator??
  • ???sscanf_s(?tokenstring,?"%s",?s,?_countof(s)?);??
  • ???sscanf_s(?tokenstring,?"%c",?&c,?sizeof(char)?);??
  • ???sscanf_s(?tokenstring,?"%d",?&i?);??
  • ???sscanf_s(?tokenstring,?"%f",?&fp?);??
  • ??
  • ???//?Output?the?data?read??
  • ???printf_s(?"String????=?%s\n",?s?);??
  • ???printf_s(?"Character?=?%c\n",?c?);??
  • ???printf_s(?"Integer:??=?%d\n",?i?);??
  • ???printf_s(?"Real:?????=?%f\n",?fp?);??
  • }??
  • ??????對于多個(gè)字符串讀入的情況,代碼如下:

  • sscanf_s(inputString,?"%s.%s.%s.%s",?s1,?s1.length,?s2,?s2.length,?s3,?s3.length,?s4,?s4.length);??
  • sscanf 函數(shù)非常好用,居然我以前一直不知道這個(gè)函數(shù)。最近朋友用VS2008寫程序時(shí)用到這個(gè)函數(shù)的安全版本 sscanf_s ,卻出現(xiàn)異常問題,無法解析字符串不說,還會(huì)崩潰。

    int sscanf_s(
    ?? const char *buffer,
    ?? const char *format?[,
    ??????argument?] ...
    );

    這是MSDN里面關(guān)于函數(shù)的定義,沒有繼續(xù)詳細(xì)查看后面的備注,以及實(shí)例的情況下。根本感覺不到sscanf 與 sscanf_s 的區(qū)別。以為仍然是像sscanf 一樣使用,以致出現(xiàn)奇怪問題。

    Example: // crt_sscanf_s.c // This program uses sscanf_s to read data items // from a string named tokenstring, then displays them.#include <stdio.h> #include <stdlib.h>int main( void ) {char tokenstring[] = "15 12 14...";char s[81];char c;int i;float fp;// Input various data from tokenstring:// max 80 character string plus NULL terminatorsscanf_s( tokenstring, "%s", s, _countof(s) );sscanf_s( tokenstring, "%c", &c, sizeof(char) );sscanf_s( tokenstring, "%d", &i );sscanf_s( tokenstring, "%f", &fp );// Output the data readprintf_s( "String = %s\n", s );printf_s( "Character = %c\n", c );printf_s( "Integer: = %d\n", i );printf_s( "Real: = %f\n", fp ); } 直到看完整個(gè)文檔,看到這個(gè)實(shí)例,才發(fā)現(xiàn)原來還有貓膩!sscanf_s 取值的時(shí)候,需要在每個(gè)取值后面指定取值的最大大小。

    在使用VS2005編譯一個(gè)程序時(shí),出現(xiàn)了很多警告,說是用的函數(shù)是不安全的,應(yīng)當(dāng)使用安全版本,即函數(shù)名稱增加“_s”的版本。
    ?
    ?警告內(nèi)容:
    ?warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead.?
    ?
    據(jù)了解,“_s”版本函數(shù)是微軟后來對c++做得擴(kuò)展,用來替代原先不安全的函數(shù),例如:printf、scanf、strcpy、fopen等等。

    詳細(xì)參考:
    ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_vccrt/html/d9568b08-9514-49cd-b3dc-2454ded195a3.htm

    原來安全版本的函數(shù),對參數(shù)和緩沖邊界做了檢查,增加了返回值和拋出異常。這樣增加了函數(shù)的安全性,減少了出錯(cuò)的幾率。
    同時(shí)這也意味著在使用這些函數(shù)時(shí),有時(shí)你不得不輸入更多的關(guān)于緩沖區(qū)大小的參數(shù),多敲幾下鍵盤能換來更少的麻煩,值得!

    下面總結(jié)了sscanf的以及sscanf_s的常用方法,也體現(xiàn)了“_s”版本函數(shù)與原函數(shù)的特別之處:

    1、sscanf和scanf的不同是輸入來源,前者是一個(gè)字符串,后者則是標(biāo)準(zhǔn)輸入設(shè)備

    2、sscanf的使用,以解析時(shí)間字符串為例,將字符串“2009-01-02_11:12:13”解析為整型年月日時(shí)分秒

    //定義
    ?char cc;
    ?tm tm_temp={0};
    ?string stime("2009-01-02_11:12:13");

    //(1) 必須嚴(yán)格按照分隔符形式匹配填寫,若遇到不匹配項(xiàng)則終止解析

    ?


    ?sscanf(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",
    ??&tm_temp.tm_year,?
    ??&tm_temp.tm_mon,?
    ??&tm_temp.tm_mday,?
    ??&tm_temp.tm_hour,?
    ??&tm_temp.tm_min,?
    ??&tm_temp.tm_sec
    ??);
    ??
    //(2) 可以不按照分割符號形式填寫,字符數(shù)必須一致,例如可以正確解析“2009/01/02_11:12:13”

    ?


    ?sscanf(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",
    ??&tm_temp.tm_year, &cc,
    ??&tm_temp.tm_mon, &cc,
    ??&tm_temp.tm_mday, &cc,
    ??&tm_temp.tm_hour, &cc,
    ??&tm_temp.tm_min, &cc,
    ??&tm_temp.tm_sec
    ??);
    ?
    //(3) 可以不按照分割符號形式填寫,字符數(shù)必須一致,同上,%1s可以等同于%c

    ?
    ?sscanf(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",
    ??&tm_temp.tm_year, &cc,
    ??&tm_temp.tm_mon, &cc,
    ??&tm_temp.tm_mday, &cc,
    ??&tm_temp.tm_hour, &cc,
    ??&tm_temp.tm_min, &cc,
    ??&tm_temp.tm_sec
    ??);

    //(4) 可以不按照分割符形式和數(shù)量填寫,類型必須一致,例如可以正確解析“2009/01/02___11:12:13”
    //這里使用了sscanf的正則表達(dá)式,與通用的正則表示類似但不完全相同,%*c表示忽略連續(xù)多個(gè)字符


    ?sscanf(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",
    ??&tm_temp.tm_year,?
    ??&tm_temp.tm_mon,?
    ??&tm_temp.tm_mday,?
    ??&tm_temp.tm_hour,?
    ??&tm_temp.tm_min,?
    ??&tm_temp.tm_sec
    ??);
    ??
    3、sscanf_s的使用

    ?//定義
    ?char cc[2];
    ?tm tm_temp={0};
    ?string stime("2009-01-02_11:12:13");

    //(1) 與sscanf第一種方法相同,可以使用"%4d-%2d-%2d_%2d:%2d:%2d"格式匹配解析

    ?


    ?sscanf_s(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",
    ???&tm_temp.tm_year,?
    ???&tm_temp.tm_mon,?
    ???&tm_temp.tm_mday,?
    ???&tm_temp.tm_hour,?
    ???&tm_temp.tm_min,?
    ???&tm_temp.tm_sec
    ???);
    ??
    //(2) 使用%c格式對數(shù)據(jù)解析時(shí),必須對相應(yīng)的緩沖區(qū)增加長度參數(shù),否則將會(huì)出錯(cuò)


    ?sscanf_s(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",
    ??&tm_temp.tm_year, &cc, 1,
    ??&tm_temp.tm_mon, &cc, 1,
    ??&tm_temp.tm_mday, &cc, 1,
    ??&tm_temp.tm_hour, &cc, 1,
    ??&tm_temp.tm_min, &cc, 1,
    ??&tm_temp.tm_sec
    ??);
    ??
    //(3) 使用%s格式對數(shù)據(jù)解析時(shí),緩沖長度必須大于字符串長度,否則不予解析


    ?sscanf_s(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",
    ???&tm_temp.tm_year, &cc, 2,
    ???&tm_temp.tm_mon, &cc, 2,
    ???&tm_temp.tm_mday, &cc, 2,
    ???&tm_temp.tm_hour, &cc, 2,
    ???&tm_temp.tm_min, &cc, 2,
    ???&tm_temp.tm_sec
    ???);

    //(4) 與sscanf一樣,sscanf_s同樣支持正則表達(dá)式


    ?sscanf_s(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",
    ??&tm_temp.tm_year,?
    ??&tm_temp.tm_mon,?
    ??&tm_temp.tm_mday,?
    ??&tm_temp.tm_hour,?
    ??&tm_temp.tm_min,?
    ??&tm_temp.tm_sec
    ??);
    ??
    通過以上對比sscanf與sscanf_s的使用,可以看出后者對緩沖區(qū)安全有了更多的考慮,從而避免了許多不經(jīng)意的煩惱。

    大家都知道sscanf是一個(gè)很好用的函數(shù),利用它可以從字符串中取出整數(shù)、浮點(diǎn)數(shù)和字符串等等。它的使用方法簡單,特別對于整數(shù)和浮點(diǎn)數(shù)來說。但新手可 能并不知道處理字符串時(shí)的一些高級用法,這里做個(gè)簡要說明吧。

      1. 常見用法。

    以下是引用片段:
      char?str[512]?=?;?
      sscanf("123456?",?"%s",?str);?
      printf("str=%sn",?str);

      2. 取指定長度的字符串。如在下例中,取最大長度為4字節(jié)的字符串。

    以下是引用片段:
      sscanf("123456?",?"%4s",?str);?
      printf("str=%sn",?str);

      3. 取到指定字符為止的字符串。如在下例中,取遇到空格為止字符串。

    以下是引用片段:
      sscanf("123456?abcdedf",?"%[^?]",?str);?
      printf("str=%sn",?str);

      4. 取僅包含指定字符集的字符串。如在下例中,取僅包含1到9和小寫字母的字符串。

    以下是引用片段:
      sscanf("123456abcdedfBCDEF",?"%[1-9a-z]",?str);?
      printf("str=%sn",?str);

      5. 取到指定字符集為止的字符串。如在下例中,取遇到大寫字母為止的字符串。

    以下是引用片段:
      sscanf("123456abcdedfBCDEF",?"%[^A-Z]",?str);?
      printf("str=%sn",?str);

    總結(jié)

    以上是生活随笔為你收集整理的sscanf,sscanf_s及其相关用法(字符串格式化为其他类型)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。