0

I'm currently trying to run a command from inside my Go program and parse an integer from the response. The command returns output like this:

6
fyb_src/ex1.fyb (1) wins!

Splitting the lines and removing the whitespace with strings.Split and strings.TrimSpaces works fine. However, while trying to parse the number into an integer I get the following error:

panic: strconv.ParseInt: parsing "0 \r1 \r2 \r3 \r4 \r5 \r6": invalid syntax

But printing the string I'm trying to parse to the terminal yields the following result:

6

I'm not really sure where to go from here. The number clearly looks like an integer to me. The error message isn't useful either (at least for me). Does anyone have an idea?

EDIT: The code I'm running

    out, _ := exec.Command(pwd+"/osx_fukyobrane_amd64", "fyb_src/"+filename, "fyb_src/salty.fyb", "t").CombinedOutput()
    parts := strings.Split(string(out), "\n")

    fmt.Println(parts[0])

    rounds, err := strconv.Atoi(strings.TrimSpace(parts[0]))
    if err != nil {
        panic(err.Error())
    }
2
  • Adding the part where you call ParseInt could help. Commented Jun 10, 2016 at 22:00
  • @cnicutar Thanks for the comment, I've added the relevant code. Commented Jun 10, 2016 at 22:04

3 Answers 3

1

It would appear that your problem is that parts[0] contains the string "0 \r1 \r2 \r3 \r4 \r5 \r6" instead of a number.

The strconv.Atoi function is looking for just one number to parse - I assume you are trying to get that first "0" in this case. If so, the problem is that this code: strings.Split(string(out), "\n") is only looking for "\n" not "\r", which is apparently what is being returned from osx_fukyobrane_amd64.

One solution would be to instead split the lines like this:

regexp.MustCompile(`[\r\n]+`).Split(parts[0], -1)

That will collapse multiple lines together into one and treat \r, \n, and \r\n (or other weird combinations) as valid line breaks.

Sign up to request clarification or add additional context in comments.

4 Comments

Actually the last \r6 contains the desired number (6). Splitting string(out) with your regular expression yields the right string for strconv.Atoi at index len(parts)-3. I don't think I really comprehend what's going on here (I get the regular expression, but not why the string "6" in the terminal would be some crazy string internally). Anyways, thank you very much for your help.
What is the format of the output you are trying to capture? You say it's the "6", but why? Is it always the 6th line down? Or the last one? or what?
The content of the first blockquote in my question is what you see in the terminal. It appears to be 6 \n fyb_src/ex1.fyb (1) wins!, but as we have seen it is not. The error message is always 0 \r1 \r2 ...\rn where n is the actual number (in this case 6). So in this case it was 0 \r1 \r2 \r3 \r4 \r5 \r6.
Hm - I would try running the command manually from the command line and sending it to a file (e.g. osx_fukyobrane_amd64 fyb_src/whatever fyb_src/salty.fyb t > temp.out) and then running hexdump on it to see exactly what bytes it's outputting, e.g. hexdump -C temp.out
1

Use strings.Fields instead of Split, it automagically handle \n and \r.

This is also much faster than using regexp, which is considerably slow in Go, although it is getting improved.

func splitAndTrim(line string) []string {
    out := strings.Fields(line)
    for i, s := range out {
        out[i] = strings.TrimSpace(s)
    }
    return out
}

playground

Comments

0

It looks like there might be some additional escaped data on that line. Try splitting by space and using that.

out, _ := exec.Command(pwd+"/osx_fukyobrane_amd64", "fyb_src/"+filename, "fyb_src/salty.fyb", "t").CombinedOutput()
parts := strings.Split(string(out), "\n")

parts = strings.Split(parts, " ")

fmt.Println(parts[0])

rounds, err := strconv.Atoi(strings.TrimSpace(parts[0]))
if err != nil {
    panic(err.Error())
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.