Home >Backend Development >Golang >Do not accept duplicate input from stdin

Do not accept duplicate input from stdin

WBOY
WBOYforward
2024-02-08 22:50:091065browse

不接受来自 stdin 的重复输入

php editor Apple will introduce you to an important note in this article: "Do not accept repeated input from stdin." In programming, we often use stdin as an input source, but repeated input may cause errors or unpredictable behavior in the program. Therefore, we need to pay attention to avoiding duplication of input when using stdin to ensure the normal operation of the program. In the following article, we will explore this problem in detail and provide some solutions and practical suggestions to help readers better handle duplicate situations of stdin input.

Question content

I have a contrived program whose goal is to echo text on standard input (as many times as necessary) and exit after 10 seconds. code show as below:

package main

import (
    "bufio"
    "fmt"
    "os"
    "time"
)

func main() {
    input := make(chan string)
    abort := make(chan bool)

    // exit after 10 sec
    go func() {
        time.Sleep(10 * time.Second)
        abort <- true
    }()

    go func() {
        cmd := bufio.NewScanner(os.Stdin)
        for cmd.Scan() {
            input <- "<- " + cmd.Text()
        }
    }()

    select {
    case <-abort:
        fmt.Println("exiting")
        return
    case cmd := <-input:
        fmt.Println(cmd)
    }
}

The problem is when I enter the first line of text, it echoes to stdout and the program exits. I want to enter as many commands as possible in 10 seconds.

What did i do wrong?

Workaround

The abort channel is closed after 10 seconds, which allows the first selection case (<-abort) to be triggered and exit the program. This is what I got

func main() {
input := make(chan string)
abort := make(chan bool)

// exit after 10 sec
go func() {
    time.Sleep(10 * time.Second)
    close(abort) // Close the channel after 10 seconds
}()

go func() {
    cmd := bufio.NewScanner(os.Stdin)
    for cmd.Scan() {
        input <- "<- " + cmd.Text()
    }
}()

for {
    select {
    case <-abort:
        fmt.Println("closing connection")
        return
    case cmd := <-input:
        fmt.Println(cmd)
    }
}
}'

I used "for" to replace the outer select statement with an infinite loop After the 10 second timeout, I close the abort channel using a close(abort) statement. This tells the select statement that a timeout has occurred and execution of the first case (<-abort) should continue when the channel is closed. I have a sezier typing so I hope you understand.

The above is the detailed content of Do not accept duplicate input from stdin. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete