TransWikia.com

Problema na entrada de valores - Golang

Stack Overflow em Português Asked by Marcelo on January 2, 2021

Estou fazendo um jogo da velha onde a entrada é um numero de 1 a 9 que corresponde ao local no campo, se eu entrar com mais de 1 digito como 44 ou "asd" é dado como entrada invalida. Porem quando eu entro com "44 4" ou "a s 5 d" ele conta como valido, não apenas como valido, mas também ele percorre todos os valores no loop do jogo, pulando a etapa de entrada, verificação. E caso contenha na entrada valores considerados validos, como por exemplo "a 1 5 d aa" os valores no campo 1 e 5 são preenchidos.

Esta é a função que recebe os valores e retorna. Fiz o teste com um Print, e mesmo recebendo mais de 1 valor, ele apenas da o Print no primeiro valor da entrada.

func getLocal(jogador int) string {
    var local string
    fmt.Printf("Vez do %d* jogador n", jogador)
    fmt.Printf("Escolha: ")
    fmt.Scan(&local)
    return local
}

Esta é a função que faz a verificação da entrada.

func veriEnt(local string) bool {
    if len(local) == 1 {
         v := regexp.MustCompile("[1-9]") 
         return v.MatchString(local)
    } else {
        return false
    }
}

A função principal onde o jogo acontece, como eu disse, quando entro com mais de um valor, as funções de entrada e verificação são ignoradas.

func main() {
    clearScream()
    var jogador, rodada = 1, 1
    for true {
        showGame()
        local := getLocal(jogador)
        ok := veriEnt(local)
        if ok {
            x, y := coordenada(local)
            attCampo(x, y, jogador)
            jogador, rodada = endTurn(jogador, rodada)
        }
        clearScream()
    }
}

Os testes que eu viz me mostraram que a entrada não é uma string com espaços ou uma lista. E que o "erro" esta em uma destas funções lsitadas, pois as outras funções apenas geram dados com base na entrada, e funcionamento delas esta como o esperado.

PS: clearScream apenas limpa a tela, showGame mostra o campo na tela e endTurn passa a vez pro aproximo jogador e adicionar 1 no contador de rodadas.

One Answer

Isso está acontecendo, porque a função fmt.Scan lê a entrada até o primeiro espaço encontrado.

Tudo que você dá como entrada no terminal, vai para um stream chamado stdin. O que a função fmt.Scan faz, é verificar se existe algo escrito no stdin, se existir, ele te retorna uma string com o conteúdo até o primeiro espaço, se não existir, ele espera pelo usuário inserir algo.

O restante do conteúdo continua no stdin, então se você inserir algo como "44 4", o fmt.Scan irá ler o "44", e a próxima vez que ele for invocado, ele irá imediatamente ler o restante do stdin e te retornar o "4".

Se você quer ler toda a entrada do usuário, pode formatar a leitura do Scanf utilizando %q para ler até o final da linha, da seguinte maneira:

fmt.Scanf("%q", &local)

Correct answer by user140828 on January 2, 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