Funcions d'entrada/sortida

Última modificació per editor1 el 2018/09/16 21:41

Objectius

  1. Entendre el concepte d’entrada i sortida.
  2. Conèixer els mètodes per a llegir dades de l’entrada.
  3. Conèixer els mètodes per a escriure dades a la sortida.

Introducció

Els programes informàtics bàsicament són manipuladors d’informació, ja sigui un programa de comptabilitat, un sistema d’intel·ligència artificial o el sistema operatiu d’un ordinador. Per tant, els programes necessiten poder obtenir aquesta informació per a processar-la i poder donar sortida als resultats. Si no tenim entrada, els programes es limitarien a fer sempre el mateix amb les mateixes dades i, si no tenim sortida, els resultats del programa mai es podrien utilitzar per a res.
Quan pensem en entrada de dades ens referim a qualsevol tipus d’entrada; poden ser les tecles que es premen en un teclat, la posició del ratolí o pantalla tàctil, un fitxer en disc, una adreça d’internet, un lector de codis de barres, una webcam o el micròfon. De la mateixa manera, quan parlem de sortida ens podem referir a un ampli ventall d’opcions, des de la pantalla de l’ordinador, un arxiu, una impressora o el sistema de control d’un robot.
Entre tots aquests dispositius hi ha dos que tenen un paper especialment rellevant: el teclat per a l’entrada de dades i la pantalla per a la sortida de dades. De fet, si no es canvia explícitament, l’entrada estàndard (o stdin de l’anglès standard input) és el teclat, i la sortida estàndard (o stdout de l’anglès standard output) és la pantalla.
En aquesta guía veurem com podem comunicar-nos amb aquests dispositius per a llegir informació des del teclat i mostrar-la en la pantalla.

1. Entrada

El primer que cal saber és que quan es premen tecles en un teclat, aquestes es converteixen en el seu codi ASCII i s’emmagatzemen com a caràcters en el que es diu un buffer, el qual conté tota la seqüència de caràcters que han escrit i que cap programa ha llegit encara.

bufferTeclat.png

Els mètodes per a llegir dades aniran llegint d’aquest buffer considerant quin tipus d’informació intentem llegir. Cal tenir en compte que el salt de línia també compta com una tecla qualsevol i es representa habitualment amb ‘\n’. Aquest buffer és una estructura coneguda com a FIFO (First In First Out), la qual cosa vol dir que ho llegirem en ordre d’arribada. A continuació es mostra un exemple del contingut del buffer a mesura que es van prement tecles del teclat:

Tecla premudaContingut del buffer
 1 ‘1’
 3 ‘3’ ‘1’
 2 ‘2’ ‘3’ ‘1’
 Salt de línia ‘\n’ ‘2’ ‘3’ ‘1’
 a ‘a’ ‘\n’ ‘2’ ‘3’ ‘1’
 Salt de línia ‘\n’ ‘a’ ‘\n’ ‘2’ ‘3’ ‘1’

Per a llegir la informació d’aquest buffer, tenim a la nostra disposició un conjunt d’instruccions en llenguatge algorísmic segons el tipus de dades que volem llegir:

InstruccióDescripció
 readChar Llegeix un caràcter del buffer
 readBoolean Llegeix un booleà del buffer
 readInteger Llegeix un enter del buffer
 readReal Llegeix un real del buffer
 readString Llegeix una cadena de caràcters del buffer

Vegem quin seria el resultat d’aplicar aquestes instruccions tenint en compte que c és una variable de tipus caràcter, i una variable de tipus enter i r una de tipus real:

Buffer InicialInstruccionsBuffer finalResultat
 ‘\n’ ‘a’ ‘\n’ ‘2’ ‘3’ ‘1’ c:= readChar() ‘\n’ ‘a’ ‘\n’ ‘2’ ‘3’ La variable c conté el valor 49 (valor ASCII del caràcter 1).
 ‘\n’ ‘a’ ‘\n’ ‘2’ ‘3’ ‘1’ i:= readInteger() ‘\n’ ‘a’ La variable i conté el valor 132. Atès que els enters poden tenir diverses xifres, es llegeix fins al salt de línia o un espai.
 ‘\n’ ‘a’ ‘\n’ ‘2’ ‘3’ ‘1’ r:= readReal() ‘\n’ ‘a’ La variable r conté el valor 132,0. Atès que els reals poden tenir diverses xifres, es llegeix fins al salt de línia o un espai.
 ‘\n’ ‘a’ c:= readChar() ‘\n’ La variable c conté el valor 97 (valor ASCII del caràcter a).
 ‘\n’ ‘a’ i:= readInteger()  Error. No es pot interpretar la lletra a com un enter.
 ‘\n’ ‘a’ r:= readReal()  Error. No es pot interpretar la lletra a com un real.

2. Sortida

En el cas de la sortida passa una cosa similar. Quan escrivim a la sortida estàndard, tota la informació queda guardada en forma de caràcters en un buffer, que es va llegint i mostrant a la pantalla.

bufferPantalla.png

Per a escriure la informació en aquest buffer i es mostri, tenim a la nostra disposició una sèrie d’instruccions en llenguatge algorísmic segons el tipus de dades que volem escriure:

InstruccióDescripció
 writeChar Escriu un caràcter al buffer
 writeBoolean Escriu un booleà al buffer
 writeInteger Escriu un enter al buffer
 writeReal Escriu un real al buffer
 writeString Escriu una cadena de caràcters al buffer

3. Entrada i sortida en C

Per a poder accedir a l’entrada i sortida estàndards en C, necessitarem utilitzar una llibreria estàndard de C. Les llibreries són conjunts de funcionalitats que estenen les instruccions bàsiques del llenguatge C, facilitant fer certes tasques. En aquest cas la llibreria es diu stdio (standard input/output) i, per a poder utilitzar-la, haurem d’importar-la al nostre programa. Per a això, haurem d’afegir la següent línia de codi al principi del nostre arxiu (sense punt i coma):

# include <stdio.h>

Una vegada importada, podem utilitzar les seves funcionalitats directament. Tant en el cas de l’entrada com en el de la sortida, cal especificar el tipus i format de les dades. Per a això, es passa la cadena de format d’entrada i sortida, on les variables que es volen llegir o escriure s’indiquen amb el símbol % i, a continuació, una lletra especificant el tipus de variable. A continuació es mostra un resum de les més habituals:

Tipus de dadaEspecificatiu de tipusExemple de dades 
 Caràcter %c 'a'
 Boolean %u 0 (equivalent de true), 1 (equivalent de false); en general, qualsevol tipus enumeratiu utilitzarà l'especificatiu %u.
 Enter %d 34 o -32
 Real %f 3.1415
 String %s "Hello World"
 Punter %p 0x000000AA; els punters els tractarem al mòdul "13. Punters en C".

A continuació veurem exemples d’aquestes cadenes de format per a l’entrada i la sortida.

3.1. Entrada

El mètode genèric per a l’entrada de dades és el mètode scanf, que espera una cadena de format indicant què ha de llegir del buffer de teclat i la llista de variables on es guardaran els valors llegits. Totes les variables han d’anar precedides del símbol & (que significa «adreça de» i que veurem en la unitat de memòria). A la taula següent tenim la traducció dels mètodes en llenguatge algorísmic anteriors, tenint en compte que c és una variable de tipus caràcter, i de tipus enter i r de tipus real:

MètodeTraducció a C
 readChar scanf("%c", &c)
 readBoolean scanf("%u", &b)
 readInteger scanf("%d", &i)
 readReal scanf("%f", &r)
 readString scanf("%s", s)

A més, en el cas de llegir un caràcter tenim la instrucció getchar que ens permet fer una assignació directa:

c=getchar();

3.2. Sortida

En el cas de la sortida per pantalla, tenim el mètode printf, que espera una cadena de format indicant què ha d’escriure i la llista de variables d’on obtenir la informació. A la taula següent tenim la traducció dels mètodes en llenguatge algorísmic anteriors, tenint en compte que c és una variable de tipus caràcter, i de tipus enter i r de tipus real:

MètodeTraducció a C
 writeChar printf("%c", c)
 writeBoolean printf("%u", b)
 writeInteger printf("%d", i)
 writeReal printf("%f", r)
 writeString printf("cadena de caràcters")
 writeString printf("%s", s)

A més, cal recordar que tenim un caràcter especial per a indicar el salt de línia (‘\n’), que el podem utilitzar en el format per a indicar que volem que es faci un salt de línia. En cas contrari tot s’escriurà seguit a la mateixa línia.
Addicionalment, podem afegir modificacions de com volem que es mostrin les dades. Aquests modificadors es posen entre el símbol % i l’especificatiu de tipus:

%[modificadors][amplada][.precisió]especificador

A continuació veiem uns quants exemples. Podeu trobar més informació aquí.

FormatValor variable Sortida
"%0d"33
"%03d"003 
"%f"3.143.14000
"%2.1f"3.143.1 

4. Exemples

4.1. Exemple 05_01: entrada

Enunciat:

Definiu un algorisme que llegeixi dos enters i calculi la seva suma. Feu la seva traducció a C.

Solució:

algorithm sum

    var 
        a: integer;
        b: integer;
        s: integer;
    end var

    a:= readInteger();
    b:= readInteger();

    s:= a + b;

end algorithm

# include <stdio.h>

int main() {
   int a;
   int b;
   int s;

    scanf("%d", &a);
    scanf("%d", &b);

    s=a+b;

   return 0;
}

4.2. Exemple 05_02: sortida

Enunciat:

Definiu un algorisme que, donades dues variables a = 2 i b = 2, escrigui per pantalla el missatge: «La suma d’a i b és 4». Feu la seva traducció a C.

Solució:

algorithm sumaSortida

    var 
        a: integer;
        b: integer;
    end var

    a:= 2;
    b:= 2;

   writeString("La suma d'a i b és :");
   writeInteger(a + b);

end algorithm

# include <stdio.h>

int main() {
   int a=2;
   int b=2;
  
    printf("La suma d'a i b és : %d", a + b);

   return 0;
}

4.3. Exemple 05_03: entrada i sortida

Enunciat:

Definiu un algorisme que requereixi tres enters i mostri per pantalla el valor mitjà dels tres. Feu la seva traducció a C.

Solució:

algorithm sumaEntradaSortida

    var 
        a: integer;
        b: integer;
        c: integer;
        m: float;
    end var

    a:= readInteger();
    b:= readInteger();
    c:= readInteger();

    m=(a+b+c)/3.0;

   writeReal(m);

end algorithm

# include <stdio.h>

int main() {
   int a;
   int b;
   int c;
   float m;

    scanf("%d", &a);
    scanf("%d", &b);
    scanf("%d", &c);

    m=(a+b+c)/3.0;

    printf("%f", m);

   return 0;
}

Resum

En aquesta guía hem vist la utilització dels mètodes scanf i printf per a llegir i escriure dades en els dispositius estàndard d’entrada i sortida. També hem vist que es pot modificar el format de les dades.

Etiquetes:
Creat per editor1 el 2018/09/16 21:41