star
star

Reputation: 41

Why is this the output of the following code wrong in GO language

This is my code written to implement a Stack. When I execute this, it generates some different kind of output totally. A screenshot of output is attached. Why is the program generating such invalid output? Is there any mistake in the code?

package main

import "fmt"

var st [100]int
var top int

func main() {
    top = -1
    ch := 0
    temp := 0
    for true {
        fmt.Println("Enter you choice:")
        fmt.Println("1. PUSH\n2. POP\n3. PRINT\n4. EXIT")
        fmt.Scanf("%d", &ch)
        switch ch {
        case 1:
            fmt.Println("Enter the value...")
            fmt.Scanf("%d", &temp)
            push(temp)
        case 2:
            temp = pop()
            if temp != -1 {
                fmt.Println("The popped value is ", temp)
            }
        case 3:
            print()
        case 4:
            break
        default:
            fmt.Println("Please enter a valid choice")
        }
    }
}

func print() {
    i := 0
    if top == -1 {
        fmt.Println("First insert elements into the stack")
    } else {
        fmt.Printf("The values are as follows")
        for i <= top {
            fmt.Println(st[i])
            i++
        }
    }
}

func pop() int {
    if top == -1 {
        fmt.Println("Please push values before popping")
        return -1
    }
    temp := st[top]
    top--
    return temp
}

func push(n int) {
    top++
    st[top] = n
}

Screen shot of the output:

enter image description here

Upvotes: 2

Views: 254

Answers (1)

icza
icza

Reputation: 418387

The problem is that you want it to work like you enter a value and press Enter which generates a newline character, and you try to scan it using fmt.Scanf(). Quoting from its doc:

Newlines in the input must match newlines in the format.

So if you want to use fmt.Scanf(), the format string must include a newline \n. But since yours doesn't, the newline is not consumed, so the next line to read the value will automatically proceed.

Easy fix: add \n to the format string:

fmt.Println("Enter you choice:")
fmt.Println("1. PUSH\n2. POP\n3. PRINT\n4. EXIT")
fmt.Scanf("%d\n", &ch)

And:

fmt.Println("Enter the value...")
fmt.Scanf("%d\n", &temp)

An alternative is to simply use fmt.Scanln() which automatically parses a whole line:

fmt.Println("1. PUSH\n2. POP\n3. PRINT\n4. EXIT")
fmt.Scanln(&ch)

// ... 

fmt.Println("Enter the value...")
fmt.Scanln(&temp)

Also, fmt.Scanf() and fmt.Scanln() return the number of successfully scanned values and an error. Be sure to check those to see if scanning succeeded.

Another error you have in your code is the Exit functionality: you used break statement in the case 4 branch. break will only break the switch and not the for! So use a return instead of break:

    case 4:
        return

Another fix could be to use labels, also note that for true { ... } is equivalent with for { ... } (you can omit the true):

mainloop:
    for {
        // ...
        switch ch {
        // ...
        case 4:
            break mainloop
        // ...
        }
    }

Upvotes: 1

Related Questions