2013-04-05 134 views
4

我希望在用sscanf處理字符串時忽略特定字段。對於sscanf的如何用sscanf忽略字段(%*被拒絕)

手冊頁說

An optional '*' assignment-suppression character: scanf() reads input as directed by the conversion specification, but discards the input. No corresponding pointer argument is required, and this specification is not included in the count of successful assignments returned by scanf().

試圖在Golang使用這個,忽略第三場:

if c, err := fmt.Sscanf(str, " %s %d %*d %d ", &iface.Name, &iface.BTx, &iface.BytesRx); err != nil || c != 3 { 

編譯OK,但在運行時ERR爲:

bad verb %* for integer

Golang DOCO沒有具體提及%*轉換規範,但它說,

Package fmt implements formatted I/O with functions analogous to C's printf and scanf.

這並不表明%*不落實,所以...我是不是做錯了?或者它剛剛被安靜地省略了? ...但是,爲什麼要編譯?

回答

3

據我所知,此任務沒有這樣的動詞(如fmt包中調用的格式說明符)。但是,你可以做的是指定一些動詞並忽略它的值。雖然這不是特別有利於記憶。理想情況下,這將工作:

fmt.Scan(&a, _, &b) 

不幸的是,它沒有。所以,你的下一個最好的選擇將是聲明變量,而忽略了一個 你不想:

var a,b,c int 
fmt.Scanf("%d %v %d", &a, &b, &c) 
fmt.Println(a,c) 

%v會讀一個空格分隔令牌。根據您掃描的內容,您可以將 流快速轉發到您需要掃描的位置。有關在緩衝區中尋找的詳細信息,請參閱this answer 。如果你使用stdio或者你不知道你的輸入可能有多長,你似乎在這裏運氣不佳。

這並不表示%*沒有執行,所以...我在做 錯了嗎?或者它剛剛被安靜地省略了? ...但是,爲什麼它會編譯?

它編譯,因爲編譯器的格式字符串只是一個字符串像任何其他。該字符串的內容在運行時通過fmt包的函數進行評估。有些C編譯器可能會檢查格式字符串 的正確性,但這是a feature,不是標準。隨着去,go vet命令將嘗試警告你有關不匹配參數的格式字符串錯誤。

編輯

對於需要解析整數行,只是關心他們中的一些特殊情況下,你可以 結合使用fmt.Scan與整數一片。下面的示例從stdin讀取3點的整數 和將它們存儲在名爲vals切片:

ints := make([]interface{}, 3) 
vals := make([]int, len(ints)) 

for i, _ := range ints { 
    ints[i] = interface{}(&vals[i]) 
} 

fmt.Scan(ints...) 
fmt.Println(vals) 

這可能是比傳統的拆分/微調/ STRCONV鏈短。它分成 指針,每個指向vals的值。然後fmt.Scan填充這些指針。有了這個,你甚至 可以忽略大部分值由值遍地分配相同的指針,你不想:

ignored := 0 

for i, _ := range ints { 
    if(i == 0 || i == 2) { 
     ints[i] = interface{}(&vals[i]) 
    } else { 
     ints[i] = interface{}(&ignored) 
    } 
} 

上面的例子會的ignore地址分配給所有值除第一而第二個,因此 通過覆蓋有效地忽略它們。

+0

感謝您的回覆。 我還沒有完全遵循。要清楚說明我的意圖 - 我希望放棄輸入的第三個字段。 即,禁止轉換爲參數。 您的代碼行似乎提供了將該字段轉換爲參數的寬度精度。 – maxfacta 2013-04-05 03:52:37

+0

哦,似乎我誤解了你的問題,我會更新我的答案。 – nemo 2013-04-05 04:01:12

+0

乾杯......「不能做」不是我想聽到的答案,但它仍然是一個答案! 我在這裏的例子被修剪以便於查看 - 我實際上是解析/ proc/net/dev的輸出,並且只對字段1,2和10感興趣。我不打算聲明7個不需要的int ...我有一個使用字符串的多線解決方案。 Split,Fields,Trim和strconv.Atoi - 在C中,我會使用單個sscanf。 – maxfacta 2013-04-05 04:54:28