How to ignore fields using sscanf (% * rejected)

I want to ignore a specific field while processing a string using sscanf.

User page for sscanf says

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().

Trying to use this in the Golang to ignore the third field:

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

OK compiles, but at runtime err is installed:

bad verb %* for integer

Golang doco does not specifically mention the% * conversion spec, but let's say

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

This does not mean that% * is not implemented, so ... Am I doing it wrong? Or was it just quietly omitted? ... but then why is it compiling?

+4
source share
1 answer

As far as I know, there is no such verb (since format specifiers are called in the fmt package) for this task. However, you can specify some verb and ignore its meaning. However, it is not particularly memory friendly. Ideally, this would work:

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

Unfortunately, this is not the case. So your next best option is to declare variables and ignore you don't want to:

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

%v will read the space-separated token. Depending on what you are viewing, you can stream to the position at which you should scan. See this answer for more information about searching in buffers. If you use stdio or you don’t know how long your entry may seem to be out of luck here.

This does not mean that% * is not implemented, so ... Am I doing this wrong? Or was it just silently omitted? ... but then why compilation?

It compiles because, for the compiler, a format string is just a string, like any other. The contents of this line are evaluated at runtime by the functions of the fmt package. Some C compilers may check format strings for correctness, but this is a function , not the norm. With go, the go vet command will try to warn you about format string errors with inconsistent arguments.

Edit

For a special case, when you need to parse a series of integers and just take care of some of them, you can use fmt.Scan in combination with a piece of integers. The following example reads 3 integers from stdin and stores them in a slice named 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) 

This is probably shorter than the regular split / trim / strconv chain. It makes a slice of pointers each of which points to a value in vals . fmt.Scan then populates these pointers. With this, you can even ignore most values ​​by assigning the same pointer over and over to values ​​you don't want:

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

In the above example, assign the ignore address to all values ​​except the first and second, thus effectively ignoring them by overwriting.

+3
source

All Articles