2013-02-24 33 views
3

我正在編寫一個程序,它將日期字符串轉換爲三個單獨的int變量:年,月,日。sscanf C++將字符串拆分爲整數有時不起作用

int m,d,y; 
sscanf("2011-03-08","%i %*[-] %i %*[-] %i",&y,&m,&d); 
cout << y<<" "<<m<<" "<<" "<<d<<std::endl; 
sscanf("2011-03-07","%i %*[-] %i %*[-] %i",&y,&m,&d); 
cout << y<<" "<<m<<" "<<" "<<d; 

如果我轉換2011-03-08 2011-03-09或者,這一天將是0,但對於2011-03-07,06 ......這一天是7,6,...正如我所期望的那樣。有人可以解釋它,爲什麼它不適用於08或09年,只爲他們?

預先感謝您!

+0

我認爲這可能是由於八進制,請嘗試使用%d – QuentinUK 2013-02-24 12:47:17

+0

你真的應該不能混合使用C和C++這樣。這些是不同的語言,所以避免在編寫C++ – LihO 2013-02-24 12:56:59

回答

4

參見man sscanf


匹配任選符號整數;下一個指針必須是一個指向int的指針。如果以0x或0X開始,則以16爲基數讀取整數;如果以0開始,則以8爲基數讀取整數;否則以基數10讀取。只使用對應於基地的字符。

08將被掃描爲八進制整數,因爲它以0開頭。但08不是有效的八進制整數,而07是。如果您使用%d而不是%i,它將按照您的預期工作。

sscanf("2011-03-08","%d %*[-] %d %*[-] %d", &y, &m, &d); 

或者也可以簡單

sscanf("2011-03-08","%d-%d-%d", &y, &m, &d); 
+0

+1時編寫C風格的代碼。然而,問這個問題的人可能應該更喜歡使用std :: istringstream而不是sscanf。 – Aleph 2013-02-24 12:50:15

+0

@AnotherTest同意,這將是下一步。但是如果他必須保留一些現有的代碼,這可能不是一個選項。 – 2013-02-24 12:52:18

+0

@AnotherTest:流並不總是一個選項。如果編譯時的格式未知,該怎麼辦?周圍有如此多的日期格式......此外,對於更復雜的解析任務,流不支持'sscanf',實際上它實現了一種小型解析器。然而,正則表達式可能更像它;特別是現在它們已經標準化了。 – 2013-02-24 14:43:57

1

你的格式字符串是錯誤的...它應該僅僅是"%4d-%02d-%02d"

它不會傷害到檢查的sscanf與if (3 != sscanf(...)) { /* failed */ }

工作太
2

問題是%i08視爲一個八進制整數,所以可能的解決方案可能是使用%d替代,,因爲這是C++,你應該使用std::istringstream#include <sstream>)代替:

int y,m,d; 
char delimiter; 

std::istringstream dateStream("2011-03-08"); 
dateStream >> y >> delimiter >> m >> delimiter >> d; 

std::cout << y << " " << m << " " << d; 
+0

你忘了驗證''''定界符''''''每次','sscanf'暗示爲你做的,所以它不完全等價。 – 2013-02-24 14:44:48

+0

@MatthieuM .:好點,雖然我不是說它完全等同於'sscanf'。我只想指出還有其他可能的解決方案。 – LihO 2013-02-24 14:50:32