Cum se convertește șirul de caractere în număr întreg în UNIX (Programare, Linux, Shell, Unix, Interactiv)

qwarentine a intrebat.

Am d1="11" și d2="07". Vreau să convertesc d1 și d2 în numere întregi și să efectuez d1-d2. Cum pot face acest lucru în UNIX?

d1 - d2 în prezent, returnează "11-07" ca rezultat pentru mine.

Comentarii

  • Ați dorit acest lucru din linia de comandă sau în mod programatic? –  > Por Levon.
5 răspunsuri
William Pursell

Soluția standard:

 expr $d1 - $d2

Puteți face, de asemenea,:

echo $(( d1 - d2 ))

dar aveți grijă că acest lucru va trata 07 ca un număr octal! (deci 07 este același lucru cu 7, dar 010 este diferit de 10).

Comentarii

  • Având în vedere că bash dispune de o sintaxă pentru specificarea bazei numerice, de ce să nu o demonstrăm aici (deși cu un avertisment privind portabilitatea)? –  > Por Charles Duffy.
  • Puteți face conversia de bază: echo $((d1-10#$d2)) Atenție: nu este același lucru cu echo $((d1-10#d2)) –  > Por Luchostein.
  • Având în vedere că bash NU este standardul și nu este garantat pe toate țintele… ce-ar fi să sărim peste bash-ismele din moment ce nu au întrebat cum să o facă în bash…? –  > Por Svartalf.
  • Aveți grijă dacă variabilele dvs. pot conține șiruri de caractere care nu sunt numere întregi sau dacă folosiți opțiuni nounset și errexit (pe care ar trebui să le folosiți întotdeauna). Am scris multe teste pentru diferite scenarii în răspunsul meu stackoverflow.com/a/59781257/117471 –  > Por Bruno Bronosky.
  • Ar trebui să vă feriți cu siguranță de valorile non-integrale și să folosiți nounset este adesea o idee bună. Dar ar trebui să niciodată folosiți errexit. –  > Por William Pursell.
Levon

Oricare dintre acestea va funcționa din linia de comandă shell. bc este probabil soluția cea mai simplă.

Folosind bc:

$ echo "$d1 - $d2" | bc

Folosind awk:

$ echo $d1 $d2 | awk '{print $1 - $2}'

Utilizare perl:

$ perl -E "say $d1 - $d2"

Folosind Python:

$ python -c "print $d1 - $d2"

toate revin

4

Comentarii

  • Nu sunt sigur dacă este o eroare sau o caracteristică a expr, awk, bc, și dc, dar toate aceste instrumente se ocupă de cazul d1=09 prin tratarea lui 09 ca fiind valoarea zecimală 9. Cu toate acestea, perl și python o tratează ca pe o eroare de sintaxă. Veți obține rezultate diferite pentru cazul d1=010 –  > Por William Pursell.
  • @WilliamPursell Interesant … Va trebui să mă uit în acest sens, informații utile, mulțumesc. –  > Por Levon.
  • Puteți să o faceți imediat cu Bash pur: echo $((d1-10#$d2)) –  > Por Luchostein.
Bruno Bronosky

Un răspuns care nu se limitează la cazul lui OP

Titlul întrebării îi conduce pe oameni aici, așa că am decis să răspund la această întrebare pentru toți ceilalți, deoarece cazul descris de OP era atât de limitat.

TL;DR

În cele din urmă am decis să scriu o funcție.

  1. Dacă doriți 0 în caz de non-int:
int(){ printf '%d' ${1:-} 2>/dev/null || :; }
  1. Dacă doriți [empty_string] în caz de non-int:
int(){ expr 0 + ${1:-} 2>/dev/null||:; }
  1. Dacă doriți să găsiți primul int sau [empty_string]:
int(){ expr ${1:-} : '[^0-9]*([0-9]*)' 2>/dev/null||:; }
  1. Dacă doriți să găsiți primul int sau 0:
# This is a combination of numbers 1 and 2
int(){ expr ${1:-} : '[^0-9]*([0-9]*)' 2>/dev/null||:; }

Dacă doriți să obțineți un cod de stare diferit de zero în cazul unui non-int, eliminați codul de stare ||: (aka sau true), dar lăsați ;

Teste

# Wrapped in parens to call a subprocess and not `set` options in the main bash process
# In other words, you can literally copy-paste this code block into your shell to test
( set -eu;
    tests=( 4 "5" "6foo" "bar7" "foo8.9bar" "baz" " " "" )
    test(){ echo; type int; for test in "${tests[@]}"; do echo "got '$(int $test)' from '$test'"; done; echo "got '$(int)' with no argument"; }

    int(){ printf '%d' ${1:-} 2>/dev/null||:; };
    test

    int(){ expr 0 + ${1:-} 2>/dev/null||:; }
    test

    int(){ expr ${1:-} : '[^0-9]*([0-9]*)' 2>/dev/null||:; }
    test

    int(){ printf '%d' $(expr ${1:-} : '[^0-9]*([0-9]*)' 2>/dev/null)||:; }
    test

    # unexpected inconsistent results from `bc`
    int(){ bc<<<"${1:-}" 2>/dev/null||:; }
    test
)

Testul de ieșire

int is a function
int ()
{
    printf '%d' ${1:-} 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '0' from '6foo'
got '0' from 'bar7'
got '0' from 'foo8.9bar'
got '0' from 'baz'
got '0' from ' '
got '0' from ''
got '0' with no argument

int is a function
int ()
{
    expr 0 + ${1:-} 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '' from '6foo'
got '' from 'bar7'
got '' from 'foo8.9bar'
got '' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument

int is a function
int ()
{
    expr ${1:-} : '[^0-9]*([0-9]*)' 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '6' from '6foo'
got '7' from 'bar7'
got '8' from 'foo8.9bar'
got '' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument

int is a function
int ()
{
    printf '%d' $(expr ${1:-} : '[^0-9]*([0-9]*)' 2>/dev/null) || :
}
got '4' from '4'
got '5' from '5'
got '6' from '6foo'
got '7' from 'bar7'
got '8' from 'foo8.9bar'
got '0' from 'baz'
got '0' from ' '
got '0' from ''
got '0' with no argument

int is a function
int ()
{
    bc <<< "${1:-}" 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '' from '6foo'
got '0' from 'bar7'
got '' from 'foo8.9bar'
got '0' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument

Notă

Am fost trimis în această gaură de iepure pentru că răspunsul acceptat nu este compatibil cu set -o nounset (aka set -u)

# This works
$ ( number="3"; string="foo"; echo $((number)) $((string)); )
3 0

# This doesn't
$ ( set -u; number="3"; string="foo"; echo $((number)) $((string)); )
-bash: foo: unbound variable

mykeaka
let d=d1-d2;echo $d;

Acest lucru ar trebui să vă ajute.

Comentarii

  • Acesta este, de fapt, același lucru cu d=$(( d1 - d2 )); echo "$d", așa cum este acoperit de răspunsul acceptat (cu același avertisment că 0-numerele prefixate sunt interpretate ca octale). –  > Por mklement0.
utilizator529758

Utilizați acest lucru:

#include <stdlib.h>
#include <string.h>

int main()
{
    const char *d1 = "11";
    int d1int = atoi(d1);
    printf("d1 = %d
", d1);
    return 0;
}

etc.

Comentarii

  • qwarentine a însemnat shell Linux. –  > Por Lukasz Czerwinski.