2014-06-06 60 views
1
我有sscanf_s問題

,基本上我有這行代碼:混淆sscanf_s

sscanf_s(line.c_str(), 
      "<float_array id=\"%*s[^\"]\" count=\"%*d\">%[^<]s", 
      numString); 

我餵養它這行文字:

<float_array id="Cube-mesh-positions-array" count="24">1 1 -1 1 -1 -1 -1 -0.9999998 -1 -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1</float_array> 

我所試圖實現讀取在count="24">之後寫入的數字數組並將其傳遞給另一個函數,但numString在通過等式後仍保留值"",從而導致後續函數失敗。如果任何人能夠提供我洞察爲什麼發生這種情況,我會非常感激。

我測試過的一個簡短的SSCCE已經揭示出問題在於其他地方,我將不得不進一步調查這一點 - 抱歉浪費你的時間,並感謝你花時間嘗試和幫助我。

+0

是什麼類型'numString'?你能給[sscce](http://www.sscce.org/)嗎?注意sscanf_s是C,因此你的問題可能會被更好地重新定義爲一個C問題,除非一些C++特定的東西是問題的一部分。 – PlasmaHH

+0

numString只是一個字符串變量(使用std :: string),並且我對C++問題的錯誤表示歉意,我使用C++並且沒有C語言經驗,因此不知道這是C函數 – ddewerg

+0

請注意,格式字符串末尾的's'是一個文字's',而不是掃描集記號的一部分。對你來說幸運的是,沒有辦法知道它在輸入字符串中無法匹配。 –

回答

5

函數sscanf_s是一個微軟發明,旨在比標準的sscanf函數「更安全」。

這樣,如果使用的是"%s""%c",它需要參數:一個是緩衝區中的寫入的輸入,和的整數指定緩衝器的可用大小,使得很長的輸入字符串不會導致緩衝區溢出。

不幸的是,對於函數的用戶(比如你自己)來說,這並不那麼明顯,導致函數的錯誤使用(這會降低隱含的「安全性」)。

Link to the Microsoft docs;請參閱「備註」部分。

所以你在這裏有什麼是未定義的行爲,因爲sscanf_s試圖從堆棧中讀取一個你沒有放置的整數。你最終幸運的是內存讀取顯然是零,所以零字節寫入numString

這應該很好地做到:

size_t BUFSIZE = 50; 
char numString[ BUFSIZE ]; 
sscanf_s(line.c_str(), 
      "<float_array id=\"%*s[^\"]\" count=\"%*d\">%[^<]s", 
      numString, BUFSIZE); 

注意numString更好實際上一個char[]。你的問題最初被標記爲C++;如果numString實際上是std::string,請注意,您不能使用scanf家族功能和std::string參數。


(對不起,編輯,聽錯了前幾次,這格式字符串的東西... ;-))

+0

輕微:「如果您使用'」%s「'或'」%c「'」還應該包含'「%[」'。 – chux

+0

@chux:實際上它是「類型字段字符c,C,s,S或字符串控制集合在[]中。」我從來沒有用過[]我自己,所以我錯誤地認爲說明符實際上是''%[] s「'。這引出了OP的代碼的另一點:後面的「s」是錯誤的。 – DevSolar

+1

確實格式更好,因爲'%[^ <]」,'(drop _2_ s)。'C' ans'S'是MS的擴展名,'sscanf_s'在附錄中的C規範中 – chux

1
char numString[ 256 ]; 
sscanf_s(line.c_str(), 
      "<float_array id=\"%*[^\"]\" count=\"%*d\">%255[^<]", 
      numString, 256); 
+0

也許再解釋一下。 – Ashigore

+0

OP代碼中有一個額外的's'。 OP還需要指定緩衝區大小。 – BLUEPIXY