I've got a single variable containing something like 1,2,3
. These are actually three values, that I want to have in three variables called v1
, v2
, v3
(but not in an array).
Right now I'm doing this in the following way:
tmp := strings.Split(*w, ",")
sw, _ := strconv.Atoi(tmp[0])
rw, _ := strconv.Atoi(tmp[1])
pw, _ := strconv.Atoi(tmp[2])
This works, although it is very repetitive and does not feel right in Go.
What would be a cleaner way to solve this issue?
Parsing data out of a string
with a specific format and storing the parsed values into variables is a perfect task for and is easily done using fmt.Sscanf()
:
src := "1,2,3"
var a, b, c int
parsed, err := fmt.Sscanf(src, "%d,%d,%d", &a, &b, &c)
fmt.Println(parsed, err, a, b, c)
Output (try it on the Go Playground):
3 <nil> 1 2 3
As noted, this is very lenient, and will also successfully parse the "1,2,3,"
and "1,2,3,4"
inputs. This may or may not be a problem (depending on your case). If you want to make it strict, you can apply this little trick:
var temp int
parsed, err := fmt.Sscanf(src+",1", "%d,%d,%d,%d", &a, &b, &c, &temp)
What we do is we append one more of the numbers that matches the input. If the original input does not end with a number (such as "1,2,3,"
), parsing will fail with a non-nil
error, and the above example gives:
3 expected integer 1 2 3
Try it on the Go Playground. Of course it will continue to parse "valid" inputs without any errors.
Note that this still accepts the input "1,2,3,4"
. We can "reduce" this trick to a single character, and we don't necessarily need a "target" variable to store it, it may simply be designated by the format string, like in this example:
parsed, err := fmt.Sscanf(src+"~", "%d,%d,%d~", &a, &b, &c)
We append a special character unlikely to happen in the input, and we expect that special character in the format string. Attempting to parse an invalid input (such as "1,2,3,"
or "1,2,3,4"
) will result in an error such as:
3 input does not match format 1 2 3
Try it on the Go Playground.