index out of range caused by string conversion in float64?

Issue

I’m new to Golang and I’m experiencing the index out of range problem which I’ve documented about but still can’t really figure out what’s causing it in my case, this is the code where it’s detecting the error:

func stringToPunto(lines []string)(punti []Punto, err error){
    for _, l := range lines {
        parts := strings.Split(l, ";")
        x, err := strconv.ParseFloat(parts[1], 64)
        
        if err != nil {
            return nil, fmt.Errorf("impossibile convertire l'ascissa: %w", err)
        }
        
        y, err := strconv.ParseFloat(parts[2], 64)
        
         if err != nil {
            return nil, fmt.Errorf("Impossibile convertire l'ordinata: %w", err)
        }
        
        punti = append(punti, Punto{
            etichetta: parts[0],
            x:         x,
            y:         y,
        })
    }
    return punti, nil
}

and this is the error I’m getting:

panic: runtime error: index out of range

goroutine 1 [running]:
main.stringToPunto(0xc00001a0c0, 0x4, 0x4, 0x1, 0x0, 0x0, 0x2, 0x4)
        /home/main.go:40 +0x495
main.main()
        /home/main.go:128 +0x321

here’s a link in case you want to check out the full code on go’s playground:
https://go.dev/play/p/KQoRovuFXEo

I believe that it’s failing to parse it in float64 maybe cause the element doesn’t exist in my context or I’m trying to access something out of the range as it says in the error, but I can really figure out how to fix it, can someone kidly explain why this occurs and how can I correct it?

Solution

Welcome to StackOverflow! There are a few changes that you will need to make. I am guessing that "soglia" is requesting the total number of points that will be entered.

Your code requests the number of points, but fails to pass a pointer to the variable that will hold the number of points. The following will fix this problem in your main() function:

fmt.Scanln(&soglia)

Note the & before the variable. The Scanln function takes a pointer argument. You were passing in a string float64. Scanln was not able to read the output into anything, so it left the input in the input queue, which was used when you started entering your points. I suspect that if you had checked the error code from Scanln, you would have found an error. I did not test that.

So, the first point was a single number, rather than a number pair.

Secondly, it woudl be wise to add instructions about how to enter numbers. It took me a while to figure out that I needed to separate the numbers by a semicolon. ;. You could add this for to your for statement in the main() funciton:

fmt.Println("Please enter a series of x;y<enter> points.  Leave a blank line when you have entered all points.")

I am not sure what the purpose of this line is:

etichetta: parts[0],

Seems to be cluttering up your punti structure, but I may not understand the intent.

Finally, I have seen this assignment in other coding classes. I do not understand why you are being asked to get a count of points prior to them being entered. Your append call allocates the space for each point and increases the space with each call to append.

Also, the loop terminates based on a blank line, but based on the number of points. So, either, add a limit in the for loop that scans in the points, or drop the "soglia" variable altogether 🙂

Of course, your assignment probably requires the soglia variable. If that is the case, you might consider a for loop like this:

 var soglia int.   // Declare it as an int.  

 ...

 fmt.Println("Please enter a series of x;y<enter> points.  Leave a blank line when you have entered all points.")
 for i := 0; i < soglia; i++ {
    scanner.Scan()
    line := scanner.Text()
    if len(line) == 0 {
        // If you use this, you would have to reset soglia
        soglia = i
        fmt.Printf("You did not enter the requested number of points.\n. soglia has been reset to %d.", soglia)
        break
    }
    lines = append(lines, line)
}

Answered By – Gardener

Answer Checked By – Marilyn (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.