Maison  >  Article  >  développement back-end  >  N'acceptez pas les entrées en double de stdin

N'acceptez pas les entrées en double de stdin

WBOY
WBOYavant
2024-02-08 22:50:091038parcourir

不接受来自 stdin 的重复输入

Éditeur PHP Apple vous présentera une remarque importante dans cet article : "Ne pas accepter les entrées répétées de stdin". En programmation, nous utilisons souvent stdin comme source d'entrée, mais des entrées répétées peuvent provoquer des erreurs ou un comportement imprévisible dans le programme. Par conséquent, nous devons veiller à éviter la duplication des entrées lors de l'utilisation de stdin pour garantir le fonctionnement normal du programme. Dans l'article suivant, nous explorerons ce problème en détail et fournirons des solutions et des suggestions pratiques pour aider les lecteurs à mieux gérer les situations de duplication d'entrée stdin.

Contenu de la question

J'ai un programme artificiel dont le but est de faire écho au texte sur une entrée standard (autant de fois que nécessaire) et de sortir après 10 secondes. Le code est le suivant :

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)
    }
}

Le problème est que lorsque j'entre la première ligne de texte, elle se répercute sur la sortie standard et le programme se termine. Je veux saisir autant de commandes que possible en 10 secondes.

Qu'est-ce que j'ai fait de mal ?

Solution de contournement

Le canal d'abandon se ferme au bout de 10 secondes, ce qui permet de déclencher le premier cas de sélection (<-abort) et de sortir du programme. C'est ce que j'ai eu

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)
    }
}
}'

J'ai utilisé "for" pour remplacer l'instruction select externe par une boucle infinie Après le délai d'attente de 10 secondes, je ferme le canal d'abandon à l'aide d'une instruction close(abort). Cela indique à l'instruction select qu'un délai d'attente s'est produit et que l'exécution du premier cas (<-abort) doit se poursuivre lorsque le canal est fermé. J'ai une frappe plus sezier donc j'espère que vous comprenez.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer