TransWikia.com

Infinite loop in Go

Stack Overflow Asked by uxtrejo on December 5, 2021

I want to have the "for loop" to loop 3 times or until the user inputs something other than an integer. Below is my code, although this runs an infinite amount of times and prints out the first value the user enters.

package main

import "fmt"
import "bufio"
import "strconv"
import "os"
import "sort"

func main(){
    emptySlice := make([]int, 3) // Capacity of 3
    fmt.Println(cap(emptySlice))
    scanner := bufio.NewScanner(os.Stdin) // Creating scanner object
    fmt.Printf("Please enter a number: ")
    scanner.Scan() // Will always scan in a string regardless if its a number

    for i := 0; i < cap(emptySlice); i++ { // Should this not run 3 times?
            input, err := strconv.ParseInt(scanner.Text(), 10, 16)
                    if err != nil{
                        fmt.Println("Not a valid entry! Ending program")
                        break
                    }
                emptySlice = append(emptySlice, int(input)) // adds input to the slice
                sort.Ints(emptySlice) // sorts the slice
                fmt.Println(emptySlice) // Prints the slice
    }   
    
}

2 Answers

The program in the question starts with cap(emptySlice) == 3. Given that each complete iteration of the loop appends a new value to empty slice, we know that cap(emptySlice) >= 3 + i. It follows that the loop does not terminate.

My homework assignment is slightly different: Read up to three integers and print them in sorted order. Here's how I did it:

func main() {
    var result []int
    scanner := bufio.NewScanner(os.Stdin)
    for i := 0; i < 3; i++ {
        fmt.Printf("Please enter a number: ")
        if !scanner.Scan() {
            // Exit on EOF or other errors.
            break
        }

        n, err := strconv.Atoi(scanner.Text())
        if err != nil {
            // Exit on bad input.
            fmt.Println(err)
            break
        }
        result = append(result, n)
    }

    sort.Ints(result)
    fmt.Println(result)
}

Answered by Taylor Rex on December 5, 2021

I think there are a couple of minor bugs, but this version should work correctly:

package main

import "fmt"
import "bufio"
import "strconv"
import "os"
import "sort"

func main() {
    emptySlice := make([]int, 3) // Capacity of 3
    fmt.Println(cap(emptySlice))
    scanner := bufio.NewScanner(os.Stdin) // Creating scanner object

    for i := 0; i < cap(emptySlice); i++ { // Should this not run 3 times?
        fmt.Printf("Please enter a number: ")
        scanner.Scan() // Will always scan in a string regardless if its a number

        input, err := strconv.ParseInt(scanner.Text(), 10, 16)
        if err != nil {
            fmt.Println("Not a valid entry! Ending program")
            break
        }
        // emptySlice = append(emptySlice, int(input)) // adds input to the slice
        emptySlice[i] = int(input)
    }

    sort.Ints(emptySlice)   // sorts the slice
    fmt.Println(emptySlice) // Prints the slice

}

I've moved the prompt into the loop, and I've replaced the append call with a direct assignment to the previously allocated slice entries. Otherwise calling append will just increase the size of the slice.

I've moved the sort and the print outside of the loop, as these seemed to be incorrectly placed too.

Answered by Justin Otto on December 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP