web-dev-qa-db-fra.com

Pourquoi les entiers dans PowerShell se comparent-ils par chiffres?

Mon code vous indique si votre nombre deviné est supérieur ou inférieur à un nombre généré aléatoirement, mais il ne semble comparer les premiers chiffres du nombre que si l'un d'eux est inférieur à 10.

[int]$GeneratedNum = Get-Random -min 1 -max 101
Write-Debug $GeneratedNum

$isQuitting = $false
Do{
    [int]$Input = Read-Host "Take a guess!"

    If($Input -lt $GeneratedNum){Write-Output "Too Low"}
    If($Input -gt $GeneratedNum){Write-Output "Too High"}
    If($Input -eq $GeneratedNum){Write-Output "Good Job!"; $isQuitting = $true}

} Until($isQuitting -eq $true)

Par exemple, lorsque $GeneratedNum = 56 et $Input = 7, il renvoie "Too High"

12
nick

C'est parce que vous comparez une chaîne à un entier. L'ordre compte.

"56" -lt 7

Est-ce réellement la même chose que:

"56" -lt "7"

Alternativement:

56 -lt "7"

vous donnerait le résultat correct. PowerShell tente de contraindre l'argument du côté droit au type du côté gauche.

Vous pouvez essayer une distribution explicite:

[int]$Input -lt $GeneratedNum
18
briantist

Le problème vient du fait que Read-Host renvoie une chaîne. Ainsi, avec votre transtypage $Input est une ArrayListEnumeratorSimple essayer:

[int]$GeneratedNum = Get-Random -min 1 -max 101
Write-Host $GeneratedNum

$isQuitting = $false
Do{
    $Input = (Read-Host "Take a guess!") -as [int]

    If($Input -lt $GeneratedNum){Write-Output "Too Low"}
    If($Input -gt $GeneratedNum){Write-Output "Too High"}
    If($Input -eq $GeneratedNum){Write-Output "Good Job!"; $isQuitting = $true}

} Until($isQuitting -eq $true)

Vous devez également utiliser try{}catch{} pour intercepter le cas où l'entrée n'est pas un entier.

Ce que vous devez comprendre, c’est que, lorsque vous utilisez des opérateurs de comparaison PowerShell, le type de la partie gauche est utilisé, de sorte que la partie droite est convertie dans le type gauche. Sachant que vous auriez pu écrire ce qui suit, où je viens de mettre le $GeneratedNum qui est un entier à gauche des comparaisons:

[int]$GeneratedNum = Get-Random -min 1 -max 101
Write-Host $GeneratedNum

$isQuitting = $false
Do{
    $Input = (Read-Host "Take a guess!")

    If($GeneratedNum -gt $Input){Write-Output "Too Low"}
    If($GeneratedNum -lt $Input){Write-Output "Too High"}
    If($GeneratedNum -eq $Input){Write-Output "Good Job!"; $isQuitting = $true}

} Until($isQuitting -eq $true)
4
JPBlanc

N'utilisez jamais une variable portant le même nom qu'une variable automatique: $input est une variable automatique.

Voir ce code, où je dirige la valeur lue à partir de l'hôte (et n'utilise pas la variable $input):

[int]$GeneratedNum = Get-Random -min 1 -max 101
Write-Debug $GeneratedNum
$isQuitting = $false
Do{
    Read-Host "Take a new guess!" | %{

        if($_ -as [int] -gt 0){
            If($_ -lt $GeneratedNum){Write-Output "Too Low"}
            If($_ -gt $GeneratedNum){Write-Output "Too High"}
            If($_ -eq $GeneratedNum){Write-Output "Good Job!"; $isQuitting = $true}
        }
    }

} Until($isQuitting -eq $true)

Important de noter que mon code traite correctement incorrect les entrées (caractères non numériques) telles que w ou des chaînes similaires (qwerty), qui font échouer les autres propositions.

Je me sers du fait que vous générez des entiers toujours supérieur à 0.

0
cherimpe

Utiliser une switch:

[int]$GeneratedNum = Get-Random -min 1 -max 101
Write-Debug $GeneratedNum

:lop Do{
    switch ((Read-Host 'Take a new guess!') -as [int])
    {
        {$_ -eq $null}{continue}
        {$_ -lt $GeneratedNum}{'Too Low';continue}
        {$_ -gt $GeneratedNum}{'Too High';continue}
        {$true}{'Good Job!';break lop}
    }

} while($true)
0
cherimpe