Llegint dades de l'usuari: scanf()
Igual que printf() escriu amb un especificador de format per variable, scanf() en fa servir els mateixos per llegir-les — però amb una diferència important: cal el caràcter & davant del nom de la variable (excepte per a cadenes, com veurem).
Exemple
int edat;
printf("Quants anys tens? ");
scanf("%d", &edat);
&edat vol dir "l'adreça de memòria d'edat": scanf() necessita saber on ha de desar el valor llegit, no el valor en si mateix.
El parany del buffer
Quan prems Intro després d'escriure un número, aquest salt de línia (\n) es queda esperant al buffer del teclat. %d el salta automàticament, però %c no — llegeix literalment el primer caràcter que troba.
El problema
int edat;
char inicial;
scanf("%d", &edat); // l'usuari escriu 16 i prem Intro
scanf("%c", &inicial); // llegeix el '\n' pendent, no la lletra!
El programa mai arriba a esperar que escriguis la lletra: es queda amb el salt de línia que ja hi havia. Ho veuràs en detall a la pestanya d'execució.
La solució
scanf(" %c", &inicial); // l'espai davant de %c salta qualsevol blanc pendent
Un espai en blanc dins del format de scanf() (excepte davant de %c) ja es salta sol; aquí l'afegim expressament per forçar-ho abans de llegir el caràcter.
Cadenes de caràcters, de moment senzilles
En C encara no hi ha un tipus "text" com str en Python: una cadena és una taula (array) de caràcters. De moment en farem prou amb l'ús bàsic, sense entrar en com funcionen les taules.
char nom[30]; // espai per fins a 29 caràcters + el final
printf("Com et dius? ");
scanf("%s", nom); // sense & !
Amb %s no es posa & davant del nom: una taula ja es comporta com una adreça de memòria. Compte: %s s'atura al primer espai, així que noms compostos ("Sant Cugat") es tallarien pel mig — és un límit que superarem més endavant.
Nombres amb decimals: double i <math.h>
Per a càlculs amb decimals que necessiten precisió, double és el tipus habitual (més precís que float). La biblioteca <math.h> hi afegeix funcions com sqrt(), pow(), log()...
Exemple
#include <stdio.h>
#include <math.h>
int main() {
double x = 4.0;
printf("L'arrel de %.2f és %.2f\n", x, sqrt(x));
return 0;
}
Important: per compilar un programa que fa servir <math.h> cal afegir l'opció -lm: gcc programa.c -o programa -lm. Sense aquesta opció el compilador no trobarà les funcions matemàtiques.
Formatar la sortida
Dos recursos molt habituals: \t (tabulador, per alinear en columnes) i %.2f (decimals amb precisió fixa).
printf("x\tx^2\tsqrt(x)\n");
printf("%.2f\t%.2f\t%.2f\n", x, x*x, sqrt(x));
El número entre el punt i la f indica quants decimals es mostren. Sense el .2, printf en mostraria 6 per defecte.
Taula de referència: seqüències d'escapament
| Codi | Significat | Codi | Significat |
|---|---|---|---|
\n | nova línia | \t | tabulador horitzontal |
\r | retorn de carro | \\ | diagonal invertida |
\' | cometa simple | \" | cometa doble |
\a | caràcter d'alarma | \0 | caràcter nul (final de cadena) |
Taula de referència: especificadors de format
| Codi | Tipus | Ús habitual |
|---|---|---|
%d | int | enter amb signe |
%f | float / double | decimal (amb scanf, double necessita %lf) |
%c | char | un sol caràcter |
%s | char[] | cadena (sense espais amb scanf) |
bonus C++: cout i cin
C++ és un superconjunt de C i permet fer entrada/sortida d'una altra manera, amb els objectes cout i cin (de la biblioteca <iostream>). No és el focus d'aquest curs, però val la pena saber que existeix.
#include <iostream>
using namespace std;
int main() {
int edat;
cout << "Quants anys tens? ";
cin >> edat;
cout << "Tens " << edat << " anys" << endl;
return 0;
}
Amb << (operador d'inserció) envies dades a la pantalla i amb >> (operador d'extracció) en llegeixes del teclat — sense especificadors de format com %d. Els fitxers C++ acaben en .cc en lloc de .c.
Mira el programa executar-se pas a pas
Encara de dalt a baix, sense condicions ni bucles — però ara amb entrada de l'usuari simulada.
Entrada de dades
Sortida i format
Codi
Variables
| Nom | Valor |
|---|
Terminal
Exercicis
Aquí no hi ha solució ni comprovació automàtica: són per escriure, compilar i provar tu mateix.
1. Municipi i codi postal
Fes un programa que demani el nom d'un municipi, un caràcter qualsevol i el seu codi postal, i després mostri les tres dades juntes en una sola línia.
%s per al nom, %c per al caràcter i %s per al codi postal (amb %d es perdria el primer zero d'un codi com 08037). Pensa on pot caldre un espai davant de %c.2. Resistències en paral·lel
Calcula la resistència equivalent de dues resistències en paral·lel: Req = (R1 · R2) / (R1 + R2). Demana R1 i R2 com a double.
R1*R2/(R1+R2) no és el mateix que R1*R2/R1+R2.3. Fahrenheit a Celsius
Demana una temperatura en graus Fahrenheit i mostra l'equivalent en graus Celsius, amb la fórmula C = (F − 32) / 1.8.
double perquè el resultat tingui decimals.4. Taxa Anual Equivalent (TAE)
Donat un interès nominal anual i (per exemple 0.05) i un nombre de pagaments n (per exemple 12), calcula la TAE amb la fórmula TAE = (1 + i/n)n − 1.
pow(base, exponent) de <math.h> (i recorda compilar amb -lm).5. Mitjana de tres nombres
Demana tres nombres reals i mostra'n la mitjana aritmètica.
scanf("%f %f %f", &a, &b, &c); — separa'ls amb espais en escriure'ls.6. Equació de segon grau
Demana els coeficients a, b i c d'una equació ax² + bx + c = 0 i calcula les seves dues solucions amb la fórmula general. Encara no cal comprovar si l'equació té solució real.
disc = b*b - 4*a*c;x1 = (-b + sqrt(disc)) / (2*a);x2 = (-b - sqrt(disc)) / (2*a);Recorda: la funció principal sempre és
int main(), no void main().