ZER IKASIKO DUDAN: Bi dimentsiotako kateen array baten ariketa bat programatuko dut. Ariketa hau hobeto programatzen da laster ikusiko den erregistroen (edo struct datu-mota) array bat erabiliz.
asTaula hiru dimentsiotako taula bat da, kateak gorde ditzakeen asTaula arrayak 40 errenkada eta 3 zutabe ditu. Errenkada bakoitza ikasle bati dagokio: Errenkadaren lehen zutabean izena biltegitzen da, bigarrenean abizena eta hirugarren zutabean ikaslearen nota gordetzen da (hirurak string[19] datu-motakoak).
Taula baten dimentsioak zehazteko, bi indize behar dira: Indize bat lerro baliodunak zehazteko eta beste indize bat baliozko zutabeak adierazteko. Baina, asTaula arraya taula bat izan arren, array horren dimentsio efektiboa zenbaki oso batek adierazten du (hiru zutabeak beti beterik daudelako). Jarraian ematen den irudian, luzera efektiboaren lana errenkadak mugatzea dela ikusten da:
iLuzeraTaula=5
asTaula
0
1
2
0
'Laura'
'Urioste'
'4.8'
1
'Joseba'
'Salazar'
'6.333'
2
'Irina'
'Belasko'
'5.666'
3
'Patxi'
'Larrabe'
'9.1'
4
'Jordi'
'Coll'
'4.25'
5
6
...
39
Eskatzen da:
Nota guztien arteko batezbesteko aritmetikoa lortu:
ZER IKASIKO DUDAN: Kateen array baten ariketa bat egingo dut.
Kateak gordetzen dituen array batekin lan egingo da. Kate bakoitzean letrak eta zifrak daude, izena eta kalifikazioa.
Ikasleen kopurua programaren hasieran irakurriko da. Hauek dira ikasle jakin baten datua den karaktere-katearen ezaugarriak:
Datuaren luzera maximoa 25+1 karaktere
Datuan izena eta nota daude
Notak hiru zifra ditu (unitatea eta 2 dezimal)
Notaren zifrak horrela datoz kokatuta katean:
Unitatea katearen lehen karakterea da
Hamartarrak katearen azken bi karaktereak dira
Notarik txikiena 0.0 da
notarik handiena 9.999 da
Letrak katearen erdian daude, zifren artean
Zenbat ikasle diren teklatuaren bitartez harturik, datuak eman, notak eskuratu eta nota guztien batezbesteko aritmetiko eta desbideratze estandarra kalkulatu. Adibidez:
Datuen arraya banatu izenen eta noten arrayak lortuz. Ikasle baten izena teklatuz emanik izenen arrayan bilatu. Izenen arraya alfabetikoki ordenatu eta ondorioz, orden bera aplikatu noten arrayari.
/* Ariketa-59_IzenakEtaKalifikazioak: zenbait kate emanik bakoitzan dauden zifrak
banatu eta eragiketa aritmetiko bat burutu. */
/*
Kateak gordetzen dituen array batekin lan egingo da. Kate bakoitzean
letrak eta zifrak daude, izena eta kalifikazioa.
Ikasleen kopurua programaren hasieran irakurriko da. Hauek dira
ikasle jakin baten datua den karaktere-katearen ezaugarriak:
- Datuaren luzera maximoa 25+1 karaktere
- Datuan izena, deitura eta nota daude
- Notak hiru zifra ditu (unitatea eta 2 dezimal)
- Notaren zifrak horrela datoz kokatuta katean:
* Unitatea katearen lehen karakterea da
* Hamartarrak katearen azken bi karaktereak dira
- Letrak katearen erdian daude, zifren artean
Zenbat ikasle diren teklatuaren bitartez harturik, datuak eman, notak
eskuratu eta nota guztien batezbestekoa eta desbideratze estandarra
kalkulatu. Adibidez:
7Eleonor45 ------> 7.45
6Peru21 ------> 6.21
8Amagoia35 ------> 8.35
9Izaro00 ------> 9.00
Batezbestekoa: (+7.45 +6.21 +8.35 +9.00)/4 = 7.753
Desbideratze estandarra: 1.047
Datuen arraya banatu izenen eta noten arrayak lortuz.
Ikasle baten izena teklatuz emanik izenen arrayan bilatu.
Izenen arraya alfabetikoki ordenatu eta ondorioz, orden bera aplikatu
noten arrayari.
*/
#include <stdio.h>
#include <string.h> // strcpy(), strcmp() eta strlen() funtzioetarako
#include <stdlib.h> // atof() funtziorako
#include <math.h> // pow() funtziorako
#define BEHEMUGA 0
#define GOIMUGA 39
#define MAX_KATEA 26
typedef char tKate25[MAX_KATEA];
typedef tKate25 tasZerrenda[GOIMUGA];
typedef float tafNotak[GOIMUGA];
// Array bat bete datuak teklatuz emanik
void KateenArrayaBete(tasZerrenda asDatuak,
int* iLuzera);
// Array baten edukia pantailaratzeko funtzioa
void KateenArrayaErakutsi(const tasZerrenda asDatuak,
int iLuzera);
// Beste array baten edukia pantailaratzeko funtzioa
void NotenArrayaErakutsi(const tafNotak afNotak,
int iLuzera);
// Ikaslearen nota lortzeko funtzioa
float IkasleBatenNotaLortu(const tKate25 sIkaslearenDatuak);
// Batezbestekoa kalkulatzeko funtzioa
float BatezbestekoaKalkulatu(const tasZerrenda asDatuak,
int iLuzera);
// Desbideratze estandarra kalkulatzeko funtzioa
float DesbideratzeaKalkulatu(const tasZerrenda asDatuak,
int iLuzera,
float fBatezbestekoa);
// Izenen eta noten arrayak sortu
void IzenenEtaNotenArrayakLortu(const tasZerrenda asDatuak,
int iLuzera,
tasZerrenda asIzenak,
tafNotak afNotak);
// Ikaslea bilatzeko funtzioa
int fniIkasleaBilatu(const tKate25 sIkaslea,
const tasZerrenda asIzenak,
int iLuzera);
// Ikaslearen izena alfabetikoki sailkatu eta nota dagokion posizioan kokatu
void IzenenEtaNotenArrayakSailkatu(tasZerrenda asIzenak,
tafNotak afNotak,
int iLuzera);
// Paraleloak diren bi arrayen edukia pantailaratzeko funtzioa
void BiArrayakErakutsi(const tasZerrenda asIzenak,
const tafNotak afNotak,
int iLuzera);
int main()
{
tasZerrenda asDatuak, asIzenak;
tafNotak afNotak;
int iLuzera;
char sIkaslea[MAX_KATEA];
int iIkasleaNon;
float fBatezbestekoa;
float fDesbideratzeEstandarra;
// Array bete eta erakutsi
KateenArrayaBete(asDatuak, &iLuzera);
KateenArrayaErakutsi(asDatuak, iLuzera);
fBatezbestekoa = BatezbestekoaKalkulatu(asDatuak, iLuzera);
printf("Batezbestekoa = %.3f\n", fBatezbestekoa);
fDesbideratzeEstandarra = DesbideratzeaKalkulatu(asDatuak, iLuzera, fBatezbestekoa);
printf("Desbideratze estandarra = %.3f\n", fDesbideratzeEstandarra);
// Izenen eta noten arrayak lortu eta erakutsi
IzenenEtaNotenArrayakLortu(asDatuak, iLuzera, asIzenak, afNotak);
printf("Datuak bi zerrendetan banaturik:\n");
KateenArrayaErakutsi(asIzenak, iLuzera);
NotenArrayaErakutsi(afNotak, iLuzera);
printf("Bilatu nahi duzun ikaslearen izena eman: ");
fgets(sIkaslea, MAX_KATEA, stdin);
sIkaslea[strlen(sIkaslea)-1] = '\0'; // azkenaurreko posizioan dagoen lerro-berri karakterea kendu
iIkasleaNon = fniIkasleaBilatu(sIkaslea, asIzenak, iLuzera);
if (iIkasleaNon == 0)
{
printf("\"%s\" izeneko ikaslerik ez dago\n", sIkaslea);
}
else
{
afNotak[iIkasleaNon] = fBatezbestekoa;
printf("Ikaslearen berritutako nota: %.2f\n", afNotak[iIkasleaNon]);
}
// Arrayak sailkatu eta erakutsi
IzenenEtaNotenArrayakSailkatu(asIzenak, afNotak, iLuzera);
printf("Ikasleen zerrenda izenez sailkaturik:\n");
BiArrayakErakutsi(asIzenak, afNotak, iLuzera);
return 0;
}
// Array bat betetzeko funtzioa
void KateenArrayaBete(tasZerrenda asDatuak, int* iLuzera)
{
int iKont;
do
{
printf("Arrayak zenbat elementu izango ditu? ");
scanf("%d", iLuzera);
fflush(stdin);
} while (*iLuzera < BEHEMUGA || *iLuzera > GOIMUGA);
for (iKont = BEHEMUGA; iKont < *iLuzera; iKont++)
{
do
{
printf("'7Joseba43' itxurako %d. elementua eman: ", iKont);
fgets(asDatuak[iKont], MAX_KATEA, stdin);
asDatuak[iKont][strlen(asDatuak[iKont])-1] = '\0'; // azkenaurreko posizioan dagoen lerro-berri karakterea kendu
// printf("\n------asDatuak[iKont]=|%s|\n------asDatuak[iKont][0]=|%c|\n------asDatuak[iKont][azkena]=|%c|------\n", asDatuak[iKont], asDatuak[iKont][0], asDatuak[iKont][strlen(asDatuak[iKont])-1]);
if (asDatuak[iKont][0] < '0' || asDatuak[iKont][0] > '9')
printf("Notaren unitatea falta da\n");
if (asDatuak[iKont][strlen(asDatuak[iKont])-2] < '0' || asDatuak[iKont][strlen(asDatuak[iKont])-2] > '9')
printf("Notaren hamarrekoa falta da\n");
if (asDatuak[iKont][strlen(asDatuak[iKont])-1] < '0' || asDatuak[iKont][strlen(asDatuak[iKont])-1] > '9')
printf("Notaren ehunekoa falta da\n");
} while ((asDatuak[iKont][0] < '0' || asDatuak[iKont][0] > '9') ||
(asDatuak[iKont][strlen(asDatuak[iKont])-2] < '0' || asDatuak[iKont][strlen(asDatuak[iKont])-2] > '9') ||
(asDatuak[iKont][strlen(asDatuak[iKont])-1] < '0' || asDatuak[iKont][strlen(asDatuak[iKont])-1] > '9'));
}
}
// Array baten edukia pantailaratzeko funtzioa
void KateenArrayaErakutsi(const tasZerrenda asDatuak, int iLuzera)
{
int iKont;
for (iKont = BEHEMUGA; iKont < iLuzera; iKont++)
printf(" %d. elementua: |%s|\n", iKont, asDatuak[iKont]);
}
// Beste array baten edukia pantailaratzeko funtzioa
void NotenArrayaErakutsi(const tafNotak afNotak, int iLuzera)
{
int iKont;
for (iKont = BEHEMUGA; iKont < iLuzera; iKont++)
printf(" %d. elementua: |%.2f|\n", iKont, afNotak[iKont]);
}
// Ikaslearen nota lortzeko funtzioa
float IkasleBatenNotaLortu(const tKate25 sIkaslearenDatuak)
{
char sNota[6];
snprintf(sNota, sizeof(sNota), "%c.%c%c", sIkaslearenDatuak[0],
sIkaslearenDatuak[strlen(sIkaslearenDatuak)-2],
sIkaslearenDatuak[strlen(sIkaslearenDatuak)-1]);
return atof(sNota);
}
// Batezbestekoa kalkulatzeko funtzioa
float BatezbestekoaKalkulatu(const tasZerrenda asDatuak, int iLuzera)
{
float fMetagailu = 0.0;
int iKont;
for (iKont = BEHEMUGA; iKont < iLuzera; iKont++)
{
fMetagailu += IkasleBatenNotaLortu(asDatuak[iKont]);
}
return fMetagailu / iLuzera;
}
// Desbideratze estandarra kalkulatzeko funtzioa
float DesbideratzeaKalkulatu(const tasZerrenda asDatuak,
int iLuzera,
float fBatezbestekoa)
{
float fMetagailu = 0.0;
int iKont;
for (iKont = BEHEMUGA; iKont < iLuzera; iKont++)
{
fMetagailu += pow((IkasleBatenNotaLortu(asDatuak[iKont]) - fBatezbestekoa), 2);
}
fMetagailu = fMetagailu / iLuzera;
return pow(fMetagailu, 0.5);
}
// Izenen eta noten arrayak sortu
void IzenenEtaNotenArrayakLortu(const tasZerrenda asDatuak,
int iLuzera,
tasZerrenda asIzenak,
tafNotak afNotak)
{
int iKont;
for (iKont = BEHEMUGA; iKont < iLuzera; iKont++)
{
afNotak[iKont] = IkasleBatenNotaLortu(asDatuak[iKont]);
strcpy(asIzenak[iKont], asDatuak[iKont] + 1);
asIzenak[iKont][strlen(asIzenak[iKont]) - 2] = '\0'; // Azken bi karaktereak kendu
}
}
// Ikaslea bilatzeko funtzioa
int fniIkasleaBilatu(const tKate25 sIkaslea,
const tasZerrenda asIzenak,
int iLuzera)
{
int iKont;
for (iKont = BEHEMUGA; iKont < iLuzera; iKont++)
{
if (strcmp(asIzenak[iKont], sIkaslea) == 0)
return iKont;
}
return 0;
}
// Ikaslearen izena alfabetikoki sailkatu eta nota dagokion posizioan kokatu
void IzenenEtaNotenArrayakSailkatu(tasZerrenda asIzenak, tafNotak afNotak, int iLuzera)
{
int k, j;
char sIzenTxikiena[MAX_KATEA];
float rLaguntzailea;
int iTxikienaNon;
for (k = BEHEMUGA; k < iLuzera-1; k++)
{
strcpy(sIzenTxikiena, asIzenak[k]);
iTxikienaNon = k;
for (j = k + 1; j < iLuzera; j++)
{
if (strcmp(asIzenak[j], sIzenTxikiena) < 0)
{
strcpy(sIzenTxikiena, asIzenak[j]);
iTxikienaNon = j;
}
}
// izena aldatu
strcpy(asIzenak[iTxikienaNon], asIzenak[k]);
strcpy(asIzenak[k], sIzenTxikiena);
// nota aldatu
rLaguntzailea = afNotak[iTxikienaNon];
afNotak[iTxikienaNon] = afNotak[k];
afNotak[k] = rLaguntzailea;
}
}
// Paraleloak diren bi arrayen edukia pantailaratzeko funtzioa
void BiArrayakErakutsi(const tasZerrenda asIzenak,
const tafNotak afNotak,
int iLuzera)
{
int iKont;
for (iKont = BEHEMUGA; iKont < iLuzera; iKont++)
printf(" %d. elementua: |%.2f| |%s|\n", iKont, afNotak[iKont], asIzenak[iKont]);
}
Zenbait ikasleren noten batezbesteko aritmetikoa kalkulatu behar da. Ikasle bakoitzaren nota, bere izena eta deiturarekin batera dator. Ikasleen kopurua programaren hasieran irakurriko da, eta kopuru hori teklatuz ematean kopurua onargarria dela ziurtatuko da.
Ikasle jakin baten datua den karaktere-katearen ezaugarriak:
Datuaren luzera maximoa 30 karaktere
Datuan izena, deitura eta nota daude
Notak hainbat zifra ditu eta edozein tokitan izan daitezke:
Gutxienez zifra bat dago
Lehen zifra unitatea da eta gainerakoak hamartarrak
Zifrak ez dira zertan jarraian egon behar
Suposatu notarik txikiena 0.0 dela
Suposatu notarik handiena 9.999 dela
Letrak direla eta, izena deitura baino lehenago dago
Izena letra larriz hasten da eta gainerakoak minuskulak dira
Deitura letra larriz hasten da eta gainerakoak minuskulak dira
Zenbat ikasle diren teklatuaren bitartez harturik, datuak eman, notak eskuratu eta nota guztien batezbestekoa kalkulatu. Adibidez:
/* Ariketa-58_HainbatNotenMedia: zenbait kate emanik bakoitzan dauden zifrak
banatu eta eragiketa aritmetiko bat burutu. */
/*
Zenbait ikasleren noten batezbesteko aritmetikoa kalkulatu behar da.
Ikasle bakoitzaren nota, bere izena eta deiturarekin batera dator.
Ikasleen kopurua programaren hasieran irakurriko da, eta kopuru hori
teklatuz ematean onargarria dela ziurtatu ahalko da eta ondorioz
exekuzio-denborako errorerik ez da gertatuko.
Ikasle jakin baten datua den karaktere-katearen ezaugarriak:
- Datuaren luzera maximoa 30 karaktere
- Datuan izena, deitura eta nota daude
- Notak hainbat zifra ditu eta edozein tokitan izan daitezke:
* Gutxienez zifra bat dago
* Lehen zifra unitatea da eta gainerakoak hamartarrak
* Zifrak ez dira zertan jarraian egon behar
* Suposatu notarik txikiena 0.0 dela
* Suposatu notarik handiena 9.999 dela
- Letrak direla eta, izena deitura baino lehenago dago
- Izena letra larriz hasten da eta gainerakoak minuskulak dira
- Deitura letra larriz hasten da eta gainerakoak minuskulak dira
Zenbat ikasle diren teklatuaren bitartez harturik, datuak eman, notak
eskuratu eta nota guztien batezbestekoa kalkulatu. Adibidez:
Eleo72norIz1a ------> 7.21
Peru6Sala8zarc ------> 6.8
AmagoiaLaka5rra ------> 5
4RuyRuiz91 ------> 4.91
(+7.21 +6.8 +5 +4.91)/4 = 5.98
*/
#include <stdio.h>
#include <string.h> // strcspn(), strncat(), strncpy() eta strcpy() funtzioetarako
#include <stdlib.h> // atof() funtziorako
#define MAX_KATEA 30
#define FALSE 0
#define TRUE 1
void LetrakNotaBanatu(char *sIkaslea, char *sLetrak, char *sNota);
void IzenAbizenBanatu(char *sLetrak, char *sIzena, char *sAbizena);
void NotarenPuntuaTxertatu(char *sNota);
int iKonprobatuNotaZeroDela(char sNota[MAX_KATEA]);
int main()
{
int iZenbatIkasle, iKont;
char sIkaslea[MAX_KATEA];
char sLetrak[MAX_KATEA];
char sIzena[MAX_KATEA];
char sAbizena[MAX_KATEA];
char sNota[MAX_KATEA];
int iErrorea;
float fNota;
float rBatukaria = 0.0;
do
{
printf("\n Zenbat ikasle izango dira (adibidez 4): ");
scanf("%d", &iZenbatIkasle);
fflush(stdin);
if (iZenbatIkasle < 1 || iZenbatIkasle > 9)
printf(" Ikasleen kopurua gutxienez 1 izan behar da eta gehienez 9");
} while (iZenbatIkasle < 1 || iZenbatIkasle > 9);
for (iKont = 1; iKont <= iZenbatIkasle; iKont++)
{
do
{
iErrorea = FALSE;
strcpy(sIzena, "");
strcpy(sAbizena, "");
strcpy(sNota, "");
printf("\n %d. ikaslearen datuak (adibidez: Eleo72norIz4a): ", iKont);
gets(sIkaslea); // katea irakurri, neurria 30+1
/*
fgets(sIkaslea, MAX_KATEA, stdin);
sIkaslea[strcspn(sIkaslea, "\n")] = 0; // lerro-berri karakterea kendu
printf(" %d. Datua, sIkaslea=|%s|", iKont, sIkaslea);
*/
LetrakNotaBanatu(sIkaslea, sLetrak, sNota);
IzenAbizenBanatu(sLetrak, sIzena, sAbizena);
// Izenik ote dagoen eta ea majuskulaz hasten den
if (strlen(sIzena) == 0)
{
iErrorea = TRUE;
printf("\n %d. txarto: %s (izenik ez dago)", iKont, sIkaslea);
}
else
{
if (sIzena[0] > 'Z')
{
iErrorea = TRUE;
printf("\n %d. txarto: %s (izenaren lehen letra ez da larria)", iKont, sIkaslea);
}
}
// Abizenik ote dagoen, egotekotan majuskulaz hasiko denez ez da konprobatzen
if (strlen(sAbizena) == 0)
{
iErrorea = TRUE;
printf("\n %d. txarto: %s (abizenik ez dago)", iKont, sIkaslea);
}
// Notarik ote dagoen eta egotekotan puntua txertatu
if (strlen(sNota) == 0)
{
iErrorea = TRUE;
printf("\n %d. datua txarto: %s (notarik ez dago)", iKont, sIkaslea);
}
else
NotarenPuntuaTxertatu(sNota);
if (!iErrorea)
{
printf("\n %d. ikaslea (kateak) >>> |%s| |%s| |%s|", iKont, sIzena, sAbizena, sNota);
fNota = atof(sNota);
printf("\n %d. ikaslea (zenbakiak) >>> fNota = %.3f\n", iKont, fNota);
if (fNota == 0.0)
iKonprobatuNotaZeroDela(sNota);
}
} while (iErrorea);
rBatukaria += fNota;
}
printf("\n Batezbestekoa = %.3f\n", rBatukaria / iZenbatIkasle);
return 0;
}
// Sarrera: sIkaslea (hasierako kate osoa)
// Irteera: sLetrak (izena eta abizena) eta sNota
void LetrakNotaBanatu(char *sIkaslea, char *sLetrak, char *sNota)
{
int iKont;
strcpy(sNota, "");
strcpy(sLetrak, "");
for (iKont = 0; iKont < strlen(sIkaslea); iKont++)
{
if (sIkaslea[iKont] >= '0' && sIkaslea[iKont] <= '9')
strncat(sNota, &sIkaslea[iKont], 1);
else
strncat(sLetrak, &sIkaslea[iKont], 1);
}
}
// Sarrera: |LeireIza|
// Emaitza: |Leire| |Iza|
void IzenAbizenBanatu(char *sLetrak, char *sIzena, char *sAbizena)
{
int iKont = 1; // 0 posizioan izenaren lehen letra majuskula
while (sLetrak[iKont] >= 'a' && sLetrak[iKont] <= 'z')
{
iKont++; // abizenaren lehen letra majuskularen posizioa zehaztu
}
strncpy(sIzena, sLetrak, iKont); // izena lortzeko n karaktere kopiatu
sIzena[iKont] = '\0'; // Amaitu izena
strcpy(sAbizena, &sLetrak[iKont]); // gainerakoa abizena da
}
// Sarrera: sNota punturik gabe
// Irteera: sNota puntuarekin
void NotarenPuntuaTxertatu(char *sNota)
{
char sBufferra[MAX_KATEA] = "";
int iKont;
if (strlen(sNota) > 1) // Zenbat zifra dauden begiratu eta dagokionean puntu bat sartu
{
sBufferra[0] = sNota[0];
sBufferra[1] = '.';
for (iKont=1; iKont < strlen(sNota); iKont++)
{
sBufferra[iKont+1] = sNota[iKont];
}
sBufferra[strlen(sNota) + 1] = '\0';
strcpy(sNota, sBufferra);
}
// printf("--------sNota=|%s|-------\n", sNota);
}
int iKonprobatuNotaZeroDela(char sNota[MAX_KATEA])
{
int iKont;
int iBaiZeroDa = TRUE;
for (iKont=0; iKont < strlen(sNota); iKont++)
{
if (iKont != 1) // puntuaren posizioa ez prozesatu
{
if (sNota[iKont] != '0')
iBaiZeroDa = FALSE;
}
printf(" Nota zero dela frogatzen... sNota[%d]=%c\n", iKont, sNota[iKont]);
}
return iBaiZeroDa;
}
Teklatuaren bidez sartutako bi esaldietan gorderik dagoen informazioan bi zati daude, azpikate batean izena eta beste azpikate batean zenbakizko nota bat. Azpikateak banatu beharko dira.
Teklatuaren bidez sartutako bi esaldietan gorderik dagoen informazioak ondoko itxura du letrak#z.zletrak non z.z azpikatea zenbaki bat adierazten duen. Helburua da bi noten arteko batezbesteko aritmetikoa kalkulatzea.
Esaldi bat gets() bitartez irakurri ondoren zer dakigu: lehenik izenaren zatia adierazten duen azpikatea dagoela, gero # banatzailea, gero zenbakia adierazten duten 3 karaktere (zifra-puntu-zifra) daude, eta, bukatzeko izenaren bigarren zatia adierazten duen azpikatea dagoela dakigu.
Programaren kodean ikus daiteke datua hartzeko gets() funtzioari deia egiten zaiola KateaIrakurri() delako funtzio barruan. Katea teklatuz jaso ondoren KateaIrakurri() funtzioan datua aztertzen da bere formatuaren zuzentasuna bermatzeko. Ikus daiteke do-while agindu errepikakorretik irteteko datuak bete behar dituela formatuaren betekizunak: Letrak[#ZifraPuntuZifra]Letrak edo bestela Letrak[#ZifraPuntuZifra].
/* Ariketa-57a_BiNotenMedia: kate pare bat emanik bakoitzean dauden zifrak
banatu eta eragiketa aritmetiko bat burutu. */
// Datua gets() bitartez irakurri.
// Ariketaren funtsa # karakterean dago, hori baita izena eta nota banatzen dituena
// eta horrekin batera jakina dela zifrak 3 direla (unitatea, puntua eta hamarrekoa).
// Datu diren bi kateak teklatuz hartzen dira KateaIrakurri() funtzioan, non datuen
// zuzentasuna aztertzen eta ziurtatzen den.
#include <stdio.h>
#include <string.h> // strstr(), strlen(), strncpy() eta strncmp() funtzioetarako
#include <stdlib.h> // atof() funtzioarako
#define FALSE 0
#define TRUE 1
// sIkaslea katea teklatuz irakurri datuen zuzuentasuna kontrolatuz
void KateaIrakurri(char* sIkaslea);
// sIkaslea kate osotik, sNota nota ateratzen duen funtzioa
void NotaEskuratu(const char* sIkaslea, char* sNota);
int main()
{
char sIkasle1[21], sIkasle2[21];
char sNota1[4], sNota2[4];
float fNota1, fNota2;
printf("////////////////////////////////////////////////////\n");
/*
do
{
printf("Lehen ikaslearen datuak eman (adibidez: Ele#7.2onor): ");
fgets(sIkasle1, sizeof(sIkasle1), stdin); // katea irakurri bere neurria zainduz
//sIkasle1[strcspn(sIkasle1, "\n")] = 0; // Enter karakterea kentzeko
sIkasle1[strlen(sIkasle1)-1] = '\0'; // Enter karakterea kentzeko
} while (strcspn(sIkasle1, "#") == strlen(sIkasle1));
// # ez badago null karakterearen posizioa itzultzen du strcspn-k eta balio hori strlen-en emaitza da
*/
printf("\nLehen ikaslearen datuak eman (adibidez: Ele#7.2onor)...\n");
KateaIrakurri(sIkasle1);
/*
do
{
printf("Bigarren ikaslearen datuak eman (adibidez: #6.8Paul): ");
fgets(sIkasle2, sizeof(sIkasle2), stdin); // katea irakurri bere neurria zainduz
//sIkasle2[strcspn(sIkasle2, "\n")] = 0; // Enter karakterea kentzeko
sIkasle2[strlen(sIkasle2)-1] = '\0'; // Enter karakterea kentzeko
} while (strcspn(sIkasle2, "#") == strlen(sIkasle2));
// # ez badago null karakterearen posizioa itzultzen du strcspn-k eta balio hori strlen-en emaitza da
*/
printf("\nBigarren ikaslearen datuak eman (adibidez: #6.8Paul)...\n");
KateaIrakurri(sIkasle2);
printf("1 ===|%s|===\n", sIkasle1);
printf("2 ===|%s|===\n\n", sIkasle2);
// kate bakoitzatik nota atera
NotaEskuratu(sIkasle1, sNota1);
printf("1 nota ===|%s|===\n", sNota1);
NotaEskuratu(sIkasle2, sNota2);
printf("2 nota ===|%s|===\n\n", sNota2);
// katetik zenbaki errelera, errorerik ez dago datuak kontrolaturik egon direlako
fNota1 = atof(sNota1);
fNota2 = atof(sNota2);
printf("Batezbestekoa: (%.1f + %.1f)/2 = %.2f\n", fNota1, fNota2, (fNota1 + fNota2) / 2);
printf("\n////////////////////////////////////////////////////\n");
return 0;
}
// sIkaslea katea teklatuz irakurri datuen zuzuentasuna kontrolatuz
void KateaIrakurri(char* sIkaslea)
{
char *pErak;
int iUnitateaNon;
int iPuntuaNon;
int iHamarrekoaNon;
do
{
printf("Ikaslearen datuak eman (adibidez: Letrak#5.7Letrak): ");
gets(sIkaslea); // katea irakurri, neurria 20+1
pErak = strstr(sIkaslea, "#");
if (pErak == NULL)
printf("Errorea!!! '#' banatzailea falta da\n");
else
{
iUnitateaNon = pErak - sIkaslea + 1;
if (sIkaslea[iUnitateaNon] < '0' || sIkaslea[iUnitateaNon] > '9')
printf("Notaren lehen zifra desegokia, '%c' ez da onartzen\n", sIkaslea[iUnitateaNon]);
iPuntuaNon = pErak - sIkaslea + 2;
if (sIkaslea[iPuntuaNon] != '.')
printf("Notari puntua falta zaio, '%c' ez da onartzen\n", sIkaslea[iPuntuaNon]);
iHamarrekoaNon = pErak - sIkaslea + 3;
if (sIkaslea[iHamarrekoaNon] < '0' || sIkaslea[iHamarrekoaNon] > '9')
printf("Notaren azken zifra desegokia, '%c' ez da onartzen\n", sIkaslea[iHamarrekoaNon]);
}
} while ((pErak == NULL) ||
(sIkaslea[iUnitateaNon] < '0' || sIkaslea[iUnitateaNon] > '9') ||
(sIkaslea[iPuntuaNon] != '.') ||
(sIkaslea[iHamarrekoaNon] < '0' || sIkaslea[iHamarrekoaNon] > '9'));
}
// sIkaslea kate osotik, sNota nota ateratzen duen funtzioa
void NotaEskuratu(const char* sIkaslea, char* sNota)
{
char* pBanatzailea;
pBanatzailea = strchr(sIkaslea, '#'); // '#' karakterearen posizioa zehaztu
if (pBanatzailea != NULL) // if hau soberan egon daiteke ziurra delako # dagoela
{ // eta zenbakiarean azpikatea zifra-puntu-zifra dela
printf("'%s' datuan '#' %d. posizioan\n", sIkaslea, (int)(pBanatzailea - sIkaslea));
strncpy(sNota, pBanatzailea+1, 3); // #-ren hurrengo hiru karaktereak kopiatu
sNota[3] = '\0'; // azpikatea amaiarazi
}
}
Teklatuaren bidez sartutako bi esaldietan gorderik dagoen informazioak ondoko itxura du IzenaZ.Z non Z.Z azpikatea zenbaki bat adierazten duen. Helburua da bi noten arteko batezbesteko aritmetikoa kalkulatzea.
Esaldi bat gets() bitartez irakurri ondoren zer dakigu: lehenik izena adierazten duen azpikatea dagoela, gero zenbakia adierazten duten 3 karaktere (zifra-puntu-zifra) daudela.
Programan ikus daiteke datua hartzean gets() funtzioari deia egiten zaiola eta ez dela kode gehiagorik gehitu datuaren egokitasuna bermatzeko. Ondorioz, baliteke atof() funtzioak huts egitea edo zenbakia moztea. Horregatik, media kalkulatu aurretik konprobatzen da atof() funtzioak ez duela huts egin. Edozein kasutan, programa honek ahultasun nabaria du, adibidez "Jokin7.23" daturako, zenbakiari dagozkion azken hiru karaktereak hartzean ".23" katea geratzen da ("7" karakterea galduz), kasu honetan atof() funtzioak 0.23 zenbaki erreala emango du eta horrekin media kalkulatuko da.
/* Ariketa-57b_BiNotenMedia: kate pare bat emanik bakoitzean dauden zifrak
banatu eta eragiketa aritmetiko bat burutu. */
// Datua gets() bitartez irakurri ondoren.
// Ariketaren funtsa katea nota azpikatearen kokapenean eta tamainan dago, nota
// azpikatea jatorrizko katearen bukaeran dago eta beti 3 karaktere dira hauek:
// (zifra-puntu-zifra).
// Ariketa honetan, datuak irakurtzean, haien zuzuentasuna ez da kontrolatzen,
// hori dela eta, atof() funtzioak huts egin dezake eta horregatik batezbestekoa
// kalkulatu ala ez kalkulatu erabaki beharra dago.
// Kode hau ez da ondo ibiliko "Jokin7.23" daturako. Izan ere, nota-katea ".23"
// izango da (azken 3 karaktereak) non '7' karakterea galdu den, eta hortik
// abiatuta atof() funtzioak 0.23 zenbakia ematen du eta media kalkula daiteke
// baina emaitza txarto dago lehen zifra galdu delako.
#include <stdio.h>
#include <string.h> // strlen() funtziorako
#include <stdlib.h> // atof() funtzioarako
#define MAX_KATEA 20
#define FALSE 0
#define TRUE 1
// Nota ateratzeko funtzioa, ez du datuen zuzuentasuna aztertzen
char* NotaBakandu(const char* sIkaslea);
int main()
{
char sIkasle1[MAX_KATEA + 1];
char sIkasle2[MAX_KATEA + 1];
char *sNota1;
char *sNota2;
float fNota1, fNota2;
int iErrore1 = FALSE;
int iErrore2 = FALSE;
/*
do
{
printf("Lehen ikaslearen datuak eman (adibidez: Eleonor7.2): ");
fgets(sIkasle1, sizeof(sIkasle1), stdin); // katea irakurri bere neurria zainduz
//sIkasle1[strcspn(sIkasle1, "\n")] = 0; // Enter karakterea kentzeko
sIkasle1[strlen(sIkasle1)-1] = '\0'; // Enter karakterea kentzeko
} while (strcspn(sIkasle1, "#") == strlen(sIkasle1));
// # ez badago null karakterearen posizioa itzultzen du strcspn-k eta balio hori strlen-en emaitza da
*/
printf("\nLehen ikaslearen datuak eman (adibidez: Eleonor7.2): ");
gets(sIkasle1); // katea irakurri, neurria 20+1
printf("sIkasle1 = |%s| \n", sIkasle1);
/*
do
{
printf("Bigarren ikaslearen datuak eman (adibidez: Paul6.8): ");
fgets(sIkasle2, sizeof(sIkasle2), stdin); // katea irakurri bere neurria zainduz
//sIkasle2[strcspn(sIkasle2, "\n")] = 0; // Enter karakterea kentzeko
sIkasle2[strlen(sIkasle2)-1] = '\0'; // Enter karakterea kentzeko
} while (strcspn(sIkasle2, "#") == strlen(sIkasle2));
// # ez badago null karakterearen posizioa itzultzen du strcspn-k eta balio hori strlen-en emaitza da
*/
printf("\nBigarren ikaslearen datuak eman (adibidez: Paul6.8): ");
gets(sIkasle2); // katea irakurri, neurria 20+1
printf("sIkasle2 = |%s| \n\n", sIkasle2);
// Lehen ikaslearen nota bakandu eta balioa lortu
sNota1 = NotaBakandu(sIkasle1);
fNota1 = atof(sNota1);
printf("sNota1 = |%s| fNota1 = |%f|\n", sNota1, fNota1);
// errorea emaitza 0.0 bada eta jatorrizko katea "0.0" ez bada
if (fNota1 == 0.0 && strcmp(sNota1, "0.0") != 0)
{
printf("sIkasle1 ---|%s|--- datua ez da egokia\n", sIkasle1);
iErrore1 = TRUE;
}
// Bigarren ikaslearen nota bakandu eta balioa lortu
sNota2 = NotaBakandu(sIkasle2);
fNota2 = atof(sNota2);
printf("sNota2 = |%s| fNota2 = |%f|\n", sNota2, fNota2);
// errorea emaitza 0.0 bada eta jatorrizko katea "0.0" ez bada
if (fNota2 == 0.0 && strcmp(sNota2, "0.0") != 0)
{
printf("sIkasle2 ---|%s|--- datua ez da egokia\n", sIkasle2);
iErrore2 = TRUE;
}
// errorerik ez bada gertatu media kalkulatu
if (!iErrore1 && !iErrore2)
printf("\nBatezbestekoa: (%f + %f)/2 = %f\n", fNota1, fNota2, (fNota1 + fNota2) / 2);
else
printf("\nBatezbestekoa ezin izan da kalkulatu\n");
return 0;
}
// Nota ateratzeko funtzioa, ez du datuen zuzuentasuna aztertzen
char* NotaBakandu(const char* sIkaslea)
{
static char sNota[4]; // 3 digituko nota eta NULL amaiera
int len = strlen(sIkaslea);
// Kate nagusiaren azken hiru karaktereak ateratzen dira
sNota[0] = sIkaslea[len-3]; // Zifra osoa
sNota[1] = sIkaslea[len-2]; // Puntua
sNota[2] = sIkaslea[len-1]; // Dezimala
sNota[3] = '\0'; // Amaiera karakterea
return sNota;
}
Teklatuaren bidez sartutako bi esaldietan gorderik dagoen informazioak ondoko itxura du letrak#z.zzz non z.zzz azpikatea zenbaki bat adierazten duen eta dezimalen kopurua aldakorra izan daitekeen datu batetik bestera, baina alde osoak beti dauka zifra bakar bat. Helburua da bi noten arteko batezbesteko aritmetikoa kalkulatzea.
Esaldi bat gets() bitartez irakurri ondoren zer dakigu: lehenik izena adierazten duen azpikatea dagoela, gero # banatzailea, gero zifra bat, gero puntua eta bukatzeko hainbat hamartar. Noski, esaldiaren zenbakizko azpikatea lortu beharko da.
Programaren kodean ikus daiteke datua hartzeko gets() funtzioaren deia eta datuaren zuzentasuna main() fungzio nagusian editen direla. Horregatik, exekuzioaren fokoa atof() funtzioara heltzean ziurtatuta dago hutsik ez duela egingo eta zenbaki erreal egokia itzuliko duela.
/* Ariketa-57c_BiNotenMedia: kate pare bat emanik bakoitzean dauden zifrak
banatu eta eragiketa aritmetiko bat burutu. */
// Datua gets() bitartez irakurri.
// Izenaren azpikatea eta zenbakiaren azpikatea # karakterez banaturik datoz datuan.
// Zenbakia adierazten duen azpikatea datuaren bukaeran dagoela dakigu, baina zenbat
// dezimal dituen ez dakigu.
// Datu diren bi kateak teklatuz hartzen dira main() funtzio nagusian, eta funtzio
// nagusian bertan aztertzen da datuaren zuzentasuna. BOndorioz, atof() funtzioaren
// arrakasta ziurtatuta dago.
#include <stdio.h>
#include <string.h> // strstr(), strlen(), strncpy() eta strchr() funtzioetarako
#include <stdlib.h> // atof() funtzioarako
#define FALSE 0
#define TRUE 1
// sIkaslea kate osotik, sNota nota ateratzen duen funtzioa
void NotaEskuratu(const char* sIkaslea, char* sNota);
int main()
{
char sIkasle1[31], sIkasle2[31];
char sNota1[16], sNota2[16];
char *pErak;
int iUnitateaNon;
int iPuntuaNon;
int iHamarrekoakNondik;
int iHamarrekoakZenbat;
int iKont;
float fNota1, fNota2;
int iErrorea;
printf("///////////////////////////////////////////////////////\n");
do
{
printf("\nLehen ikaslearen datuak eman (adibidez: Helene#7.245): ");
gets(sIkasle1); // katea irakurri, neurria 30+1
pErak = strstr(sIkasle1, "#");
if (pErak == NULL)
printf("Errorea!!! '#' banatzailea falta da\n");
else
{
iUnitateaNon = pErak - sIkasle1 + 1;
if (sIkasle1[iUnitateaNon] < '0' || sIkasle1[iUnitateaNon] > '9')
printf("Notaren lehen zifra desegokia, '%c' ez da onartzen\n", sIkasle1[iUnitateaNon]);
iPuntuaNon = pErak - sIkasle1 + 2;
if (sIkasle1[iPuntuaNon] != '.')
printf("Notari puntua falta zaio, '%c' ez da onartzen\n", sIkasle1[iPuntuaNon]);
iHamarrekoakNondik = pErak - sIkasle1 + 3;
iHamarrekoakZenbat = strlen(sIkasle1) - iHamarrekoakNondik;
printf("iHamarrekoakNondik=%d\tiHamarrekoakZenbat=%d", iHamarrekoakNondik, iHamarrekoakZenbat);
iErrorea = FALSE;
for (iKont = 0; iKont < iHamarrekoakZenbat; iKont++)
{
printf("\niKont=%d \t sIkasle1[%2d]=%c", iKont, iKont+iHamarrekoakNondik, sIkasle1[iKont+iHamarrekoakNondik]);
if (sIkasle1[iKont+iHamarrekoakNondik] < '0' || sIkasle1[iKont+iHamarrekoakNondik] > '9')
iErrorea = TRUE;
}
if (iErrorea == TRUE)
printf("\nDezimaletan errorea dago\n");
}
} while ((pErak == NULL) ||
(sIkasle1[iUnitateaNon] < '0' || sIkasle1[iUnitateaNon] > '9') ||
(sIkasle1[iPuntuaNon] != '.') ||
(iErrorea == TRUE));
printf("\n");
printf("1. datua ===|%s|===\n", sIkasle1);
printf("1. '%s' datuak %d karaktere ditu\n", sIkasle1, (int)strlen(sIkasle1));
// katetik nota atera
NotaEskuratu(sIkasle1, sNota1);
printf("1. nota: sNota1===|%s|===\n", sNota1);
// katetik zenbaki errealera igaro
fNota1 = atof(sNota1);
printf("1. nota: fNota1=%f\n", fNota1);
printf("\n");
do
{
printf("\nBigarren ikaslearen datuak eman (adibidez: Paul#6.8): ");
gets(sIkasle2); // katea irakurri, neurria 30+1
pErak = strchr(sIkasle2, '#');
if (pErak == NULL)
printf("Errorea!!! '#' banatzailea falta da\n");
else
{
iUnitateaNon = pErak - sIkasle2 + 1;
if (sIkasle2[iUnitateaNon] < '0' || sIkasle2[iUnitateaNon] > '9')
printf("Notaren lehen zifra desegokia, '%c' ez da onartzen\n", sIkasle2[iUnitateaNon]);
iPuntuaNon = pErak - sIkasle2 + 2;
if (sIkasle2[iPuntuaNon] != '.')
printf("Notari puntua falta zaio, '%c' ez da onartzen\n", sIkasle2[iPuntuaNon]);
iHamarrekoakNondik = pErak - sIkasle2 + 3;
iHamarrekoakZenbat = strlen(sIkasle2) - iHamarrekoakNondik;
printf("\niHamarrekoakNondik=%d\tiHamarrekoakZenbat=%d", iHamarrekoakNondik, iHamarrekoakZenbat);
iErrorea = FALSE;
for (iKont = 0; iKont < iHamarrekoakZenbat; iKont++)
{
printf("\niKont=%d \t sIkasle2[%2d]=%c", iKont, iKont+iHamarrekoakNondik, sIkasle2[iKont+iHamarrekoakNondik]);
if (sIkasle2[iKont+iHamarrekoakNondik] < '0' || sIkasle2[iKont+iHamarrekoakNondik] > '9')
iErrorea = TRUE;
}
if (iErrorea == TRUE)
printf("\nDezimaletan errorea dago\n");
}
} while ((pErak == NULL) ||
(sIkasle2[iUnitateaNon] < '0' || sIkasle2[iUnitateaNon] > '9') ||
(sIkasle2[iPuntuaNon] != '.') ||
(iErrorea == TRUE));
printf("\n");
printf("2. datua ===|%s|===\n", sIkasle2);
printf("2. '%s' datuak %d karaktere ditu\n", sIkasle2, (int)strlen(sIkasle2));
// katetik nota atera
NotaEskuratu(sIkasle2, sNota2);
printf("2. nota: sNota2===|%s|===\n", sNota2);
// katetik zenbaki errealera igaro
fNota2 = atof(sNota2);
printf("2. nota: fNota2=%f\n", fNota2);
// errorerik ez da gertatu datuak kontrolatuak izan direlako haien irakurketan
printf("\nBatezbestekoa: (%f + %f)/2 = %f\n", fNota1, fNota2, (fNota1 + fNota2) / 2);
printf("\n///////////////////////////////////////////////////////\n");
return 0;
}
// sIkaslea kate osotik, sNota nota ateratzen duen funtzioa
void NotaEskuratu(const char* sIkaslea, char* sNota)
{
char* pBanatzaileaNon;
int iNonHastenDa;
int iLuzeraOsoa;
pBanatzaileaNon = strchr(sIkaslea, '#'); // '#' karakterearen posizioa zehaztu
iNonHastenDa = (int)(pBanatzaileaNon - sIkaslea) +1; // zenbakiaren azpikatea non hasten da
printf("'%s' datuan '#' ostekoa %d posizioan hasten da\n", sIkaslea, iNonHastenDa);
iLuzeraOsoa = strlen(sIkaslea);
printf("'%s' datuan %d karaktere daude\n", sIkaslea, iLuzeraOsoa);
printf("'%s' datuan zenbaki-azpikateak %d karaktere ditu\n", sIkaslea, iLuzeraOsoa-iNonHastenDa);
strncpy(sNota, pBanatzaileaNon + 1, iLuzeraOsoa-iNonHastenDa); // notaren karaktereak kopiatu
sNota[iLuzeraOsoa-iNonHastenDa] = '\0'; // azpikatea amaiarazi
}
Teklatuaren bidez sartutako bi esaldietan gorderik dagoen informazioak ondoko itxura du izenaZZZ.ZZZZ non ZZZ.ZZZZ azpikatea zenbaki bat adierazten duen. Kontutan izan, zati osoaren zifren kopurua eta dezimalen kopurua aldakorrak izan daitezkeela datu batetik bestera. Helburua da bi noten arteko batezbesteko aritmetikoa kalkulatzea.
Esaldi bat gets() bitartez irakurri ondoren zer dakigu: lehenik izena adierazten duen azpikatea dagoela eta ondoren zenbakia adierazten duen azpikatea dagoela. Noski, esaldiaren zenbakizko azpikatea lortu beharko da.
Programa honetan, datuak irakurtzean, haien zuzuentasuna ez da asko kontrolatzen, izenik dagoen ala ez frogatzen da, notarik dagoen ala ez frogatzen da ere (notari dagokiola, gutxienez zifra bat daukala frogatzen da), noski, lehen zifra horren ostean letrarik balego atof() funtzioak ez luke huts egingo baina ematen duen zenbakia ahal duena da (mozturik geratzen baita).
/* Ariketa-57d_BiNotenMedia: kate pare bat emanik bakoitzean dauden zifrak
banatu eta eragiketa aritmetiko bat burutu. */
// Datua gets() bitartez irakurri.
// Izenaren azpikatea eta zenbakiaren azpikatea banatzailerik ez daukate, zenbakiaren
// dezimal kopurua ezezaguna da ere. Hori bai, ziurtzat jo dezakegu, datuaren hasieran
// izenari dagokion azpikatea doala eta ondoren zenbakia adierazten duen azpikatea.
// Ariketa honetan, datuak irakurtzean, haien zuzuentasuna ez da asko kontrolatzen,
// izena dagoela frogatzen da, nota dagoela frogatzen da ere (nota, gutxienez zifra bat
// dagoela frogatzen da), lehen zifra horren ostean letrarik balego atof() funtzioak
// ez du huts egiten baina ematen duen zenbakia ahal duena da.
#include <stdio.h>
#include <string.h> // strlen() funtziorako
#include <stdlib.h> // atof() funtziorako
#define MAXIMOA 31
// sIkaslea katean notaren lehen zifrako (edo puntuaren) posizioa itzuli
int NotaAurkitu(const char* sIkaslea);
int main()
{
char sIkasle1[MAXIMOA], sIkasle2[MAXIMOA]; // 30+1
char sNota1[MAXIMOA/2+1], sNota2[MAXIMOA/2+1]; // 15+1
int iNotaNonHastenDa;
int iZenbatZifra;
int iKont;
int iIndizea;
float fNota1, fNota2;
printf("///////////////////////////////////////////////////////\n");
do
{
printf("\nLehen ikaslearen datuak eman (adibidez: Helene73.9245): ");
gets(sIkasle1); // katea irakurri, neurria 30+1
iNotaNonHastenDa = NotaAurkitu(sIkasle1);
if (iNotaNonHastenDa == -1)
printf("\nDatuari nota falta zaio\n");
if (iNotaNonHastenDa == 0)
printf("\nDatuari izena falta zaio, lehen letra bezala '%c' ez da onartzen\n", sIkasle1[iNotaNonHastenDa]);
if (iNotaNonHastenDa > 0)
printf("\niNotaNonHastenDa=%d \t sIkasle1[%d]=%c", iNotaNonHastenDa, iNotaNonHastenDa, sIkasle1[iNotaNonHastenDa]);
} while (iNotaNonHastenDa == 0 || iNotaNonHastenDa == -1);
iZenbatZifra = strlen(sIkasle1) - iNotaNonHastenDa;
printf("\niZenbatZifra=%d \t iAzkenaNon=%d \t sIkasle1[%d]=%c\n", iZenbatZifra, (int)strlen(sIkasle1)-1, (int)strlen(sIkasle1)-1, sIkasle1[(int)strlen(sIkasle1)-1]);
iIndizea = 0;
for (iKont=iNotaNonHastenDa; iKont < strlen(sIkasle1); iKont++)
{
sNota1[iIndizea] = sIkasle1[iKont];
iIndizea++;
}
sNota1[iIndizea] = '\0';
printf("\nsNota1 = |%s|", sNota1);
printf("\n");
printf("1. datua ===|%s|===\n", sIkasle1);
printf("1. '%s' datuak %d karaktere ditu\n", sIkasle1, (int)strlen(sIkasle1));
fNota1 = atof(sNota1);
printf("1. nota: %f\n", fNota1);
printf("\n");
do
{
printf("\nBigarren ikaslearen datuak eman (adibidez: Paul68.1): ");
gets(sIkasle2); // katea irakurri, neurria 30+1
iNotaNonHastenDa = NotaAurkitu(sIkasle2);
if (iNotaNonHastenDa == -1)
printf("\nDatuari nota falta zaio\n");
if (iNotaNonHastenDa == 0)
printf("\nDatuari izena falta zaio, lehen letra bezala '%c' ez da onartzen\n", sIkasle2[iNotaNonHastenDa]);
if (iNotaNonHastenDa > 0)
printf("\niNotaNonHastenDa=%d \t sIkasle2[%d]=%c", iNotaNonHastenDa, iNotaNonHastenDa, sIkasle2[iNotaNonHastenDa]);
} while (iNotaNonHastenDa == 0);
iZenbatZifra = strlen(sIkasle2) - iNotaNonHastenDa;
printf("\niZenbatZifra=%d \t iAzkenaNon=%d \t sIkasle2[%d]=%c\n", iZenbatZifra, (int)strlen(sIkasle2)-1, (int)strlen(sIkasle2)-1, sIkasle2[(int)strlen(sIkasle2)-1]);
iIndizea = 0;
for (iKont=iNotaNonHastenDa; iKont < strlen(sIkasle2); iKont++)
{
sNota2[iIndizea] = sIkasle2[iKont];
iIndizea++;
}
sNota2[iIndizea] = '\0';
printf("\nsNota2 = |%s|", sNota2);
printf("\n");
printf("2. datua ===|%s|===\n", sIkasle2);
printf("2. '%s' datuak %d karaktere ditu\n", sIkasle2, (int)strlen(sIkasle2));
fNota2 = atof(sNota2);
printf("2. nota: %f\n", fNota2);
// errorerik ez da gertatu datuak kontrolatuak izan direlako
printf("\nBatezbestekoa: (%f + %f)/2 = %f\n", fNota1, fNota2, (fNota1 + fNota2) / 2);
printf("\n///////////////////////////////////////////////////////\n");
return 0;
}
// sIkaslea katean notaren lehen zifrako (edo puntuaren) posizioa itzuli
int NotaAurkitu(const char* sIkaslea)
{
int iKont;
iKont = -1;
do
{
iKont++;
printf("\niKont=%d \t sIkaslea[%d]=%c", iKont, iKont, sIkaslea[iKont]);
} while ((sIkaslea[iKont] < '0' || sIkaslea[iKont] > '9') && (sIkaslea[iKont] != '.') &&
(iKont < MAXIMOA));
//printf("\niKont=%d \t sIkaslea[%d]=%c\n", iKont, iKont, sIkaslea[iKont]);
if (iKont == MAXIMOA)
return -1;
else
return iKont;
}
ZER IKASIKO DUDAN: Arrayen ariketa bat egingo dut.
Teklatuaren bidez sartutako esaldia karaktereka aztertu aldaketa hauek eginez:
Letra bokala bada, majuskuletara igaro
Bokala ez den letra bada, minuskuletara igaro
Gainerako karaktereak ez aldatu
Esaldi bat fgets() bitartez irakurri ondoren (noski, azken lerro-berri karakterea kendu beharko da), esaldiko karaktere guztiak banan-banan arakatu zein aldaketa aplikatuko zaion erabakia hartuz.
/* Ariketa-56_LarriakXeheak: kate bat emanik bokalak majuskuletan eta
eta gainerako letrak minuskuletan jarri. */
// Datua fgets() bitartez irakurri ondoren, azken INTRO karakterea kendu beharko da.
// Ariketaren funtsa katea karaktereka prozesatzean dago.
#include <stdio.h>
#include <string.h> // strcspn() eta strlen() funtzioetarako
#include <ctype.h> // toupper() eta tolower() funtzioetarako
#include <stdbool.h> // bool datu-motarako
bool fnboBokalaDa(char letra);
int main()
{
char sEsaldia[21]; // gehienez 20 karakteredun katea (+1 posizio bat '\0' mugatzailerako)
int i;
printf("\n//////////////////////////////////////\n\n");
printf("sEsaldia eman: ");
fgets(sEsaldia, sizeof(sEsaldia), stdin); // katea irakurri bere neurria zainduz
//sEsaldia[strcspn(sEsaldia, "\n")] = '\0'; // Enter karakterea kendu
sEsaldia[strlen(sEsaldia)-1] = '\0'; // Enter karakterea kentzeko
printf("\n");
printf("---|01234567890123456789|--- gehienez 20\n");
printf("===|%s|===\n", sEsaldia);
// kate osoa prozesatu karaktereka
for (i = 0; i < strlen(sEsaldia); i++)
{
if (fnboBokalaDa(sEsaldia[i]))
{
sEsaldia[i] = toupper(sEsaldia[i]); // bokal bada majuskuletan jarri
} else {
sEsaldia[i] = tolower(sEsaldia[i]); // ez bada bokal minuskuletan jarri
}
}
printf("===|%s|===\n", sEsaldia);
printf("\n//////////////////////////////////////\n\n");
return 0;
}
// Karaktere bat bokal ote den aztertzen duen funtzioa
bool fnboBokalaDa(char letra)
{
switch (tolower(letra))
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true; // bokala da
default:
return false; // ez da bokala
}
}
Ze nekeza inori atea irekitzea eztikeria eta ironia zekenez [ZENEKEZAINORIATEAIREKITZEAEZTIKERIAETAIRONIAZEKENEZ]
Esaldi bat fgets() bitartez irakurri ondoren (noski, azken INTRO karakterea kendu beharko da), esaldia garbitu beharko da letrak soilik utzita. Ondoren hitzak banatu beharko dira eta horretarako strtok() funtzioa erabiliko da.
/* Ariketa-55_Palindromoak: kate bat emanik palindromoa den aztertu. */
// Datua fgets() bitartez irakurri ondoren, azken INTRO karakterea kendu beharko da.
// Soilik letrak mantenduz esaldia garbitu ondoren, fnboPalindromoaDa() delako
// funtzio boolearrak erabakiko du emandako esaldia palindromoa den ala ez.
#include <stdio.h>
#include <string.h> // strcspn() eta strlen() funtzioetarako
#include <ctype.h> // toupper() funtziorako
#include <stdbool.h> // bool datu-motarako
#include <conio.h> // getch() funtziorako
void fnsLarrizIdatzi(char *sEsaldi);
void fnsKateaGarbitu(const char *sEsaldi, char *sK);
bool fnboPalindromoaDa(const char *sEsaldi);
int main()
{
char sKatea[256];
char sKateGarbi[256];
char cAukera;
printf("Palindromoak aztertzeko programa\n");
do
{
printf("\n\nSar ezazu aztertu behar den testua: ");
fgets(sKatea, sizeof(sKatea), stdin);
sKatea[strcspn(sKatea, "\n")] = 0; // RETURN karakterea kendu, modu bat
// sKatea[strlen(sKatea)-1] = '\0'; // RETURN karakterea kendu, beste modu bat
fnsLarrizIdatzi(sKatea);
fnsKateaGarbitu(sKatea, sKateGarbi);
if (fnboPalindromoaDa(sKateGarbi))
{
printf("---> %s <--- palindromoa da\n", sKateGarbi);
}
else
{
printf("---> %s <--- ez da palindromoa\n", sKateGarbi);
}
printf("\nBeste testu bat aztertu nahi duzu: (B ala E): ");
cAukera = toupper(getch());
} while (cAukera == 'B');
printf("\n\n");
return 0;
}
void fnsLarrizIdatzi(char *sEsaldi)
{
for (int i = 0; sEsaldi[i] != '\0'; i++)
{
switch (sEsaldi[i])
{
case 'ñ':
sEsaldi[i] = 'Ñ';
break;
case 'á':
case 'à':
case 'â':
case 'Á':
case 'À':
case 'Â':
sEsaldi[i] = 'A';
break;
case 'é':
case 'è':
case 'ê':
case 'É':
case 'È':
case 'Ê':
sEsaldi[i] = 'E';
break;
case 'í':
case 'ì':
case 'î':
case 'Í':
case 'Ì':
case 'Î':
sEsaldi[i] = 'I';
break;
case 'ó':
case 'ò':
case 'ô':
case 'Ó':
case 'Ò':
case 'Ô':
sEsaldi[i] = 'O';
break;
case 'ú':
case 'ù':
case 'û':
case 'Ú':
case 'Ù':
case 'Û':
sEsaldi[i] = 'U';
break;
default:
sEsaldi[i] = toupper(sEsaldi[i]);
}
}
}
void fnsKateaGarbitu(const char *sEsaldi, char *sKateGarbi)
{
int k = 0;
for (int i = 0; sEsaldi[i] != '\0'; i++)
{
if ((sEsaldi[i] >= 'A' && sEsaldi[i] <= 'Z') || sEsaldi[i] == 'Ñ')
{
sKateGarbi[k++] = sEsaldi[i];
}
}
sKateGarbi[k] = '\0';
}
bool fnboPalindromoaDa(const char *sEsaldi)
{
int iLuz = strlen(sEsaldi);
for (int iKont = 0; iKont < iLuz / 2; iKont++)
{
if (sEsaldi[iKont] != sEsaldi[iLuz - iKont - 1])
{
return false; // ez da palindromoa
}
}
return true; // palindromoa da
}
ZER IKASIKO DUDAN: Arrayen ariketa bat egingo dut.
Esaldi bat fgets() bitartez irakurri ondoren (noski, azken INTRO karakterea kendu beharko da), esaldiaren hitzak banatu beharko dira eta horretarako strtok() funtzioa erabiliko da.
/* Ariketa-54_Akronimoak: kate bat emanik bere akronimoak lortzen ditu. */
// Datua fgets() bitartez irakurri ondoren, azken INTRO karakterea kendu beharko da.
// Ariketaren funtsa strtok() funtzioaren erabileran dago.
#include <stdio.h>
#include <stdlib.h> // system(cls) funtziorako
#include <string.h> // strtok(), strlen(), strcpy() eta strcspn() funtzioetarako
#include <ctype.h> // toupper() funtziorako
#include <stdbool.h> // bool datu-motarako
#include <conio.h> // getch() funtziorako
void AkronimoakLortu(char* sEsaldia, char* sEmaitza);
void KateaIkusi(const char sKatea[101]);
int main()
{
char sKatea[101];
char sKateKopia[101];
char sEmaitza[51];
char cAukera;
int iReturnIndizea;
int iZeroKarakIndizea;
printf("Esaldi baten akronimoak lortzeko programa.\n\n");
// begizta nagusia
do
{
// esaldia eskatu erabiltzaileari
do
{
printf("Sar ezazu sarrerako testua: ");
fgets(sKatea, sizeof(sKatea), stdin);
iReturnIndizea = strcspn(sKatea, "\n");
printf("RETURN karakterea %d. posizioan dago\n", iReturnIndizea);
iZeroKarakIndizea = strcspn(sKatea, "\0");
printf(" ZERO karakterea %d. posizioan dago\n", iZeroKarakIndizea);
KateaIkusi(sKatea);
sKatea[iReturnIndizea] = '\0'; // RETURN karakterea kendu
//sKatea[strlen(sKatea)-1] = '\0'; // RETURN karakterea kentzeko
} while (strlen(sKatea) == 0); // kate hutsa ez dugu onartzen
strcpy(sKateKopia, sKatea);
AkronimoakLortu(sKateKopia, sEmaitza);
printf("%s ---> %s\n", sKatea, sEmaitza);
// beste iterazio bat?
printf("Beste testuren bat aztertu nahi duzu: (B ala E): ");
do
{
cAukera = toupper(getch());
} while ((cAukera != 'B') && (cAukera != 'E'));
system("cls"); // pantaila garbitzeko
} while (cAukera != 'E');
return 0;
}
// Akronimoak lortzen dituen funtzioa, ssEsaldia sarrerako parametroa
// espazioen arabera mozten joan eta iterazio bakoitzeko lehen letra hartu
void AkronimoakLortu(char* sEsaldia, char* sEmaitza)
{
char *erakTokena;
bool boLehendabizikoa = true;
char sLaguntzailea[3];
// sarrerako katea larrietan jarri
for(int i = 0; sEsaldia[i]; i++)
{
sEsaldia[i] = toupper(sEsaldia[i]);
}
// hitz bakoitzaren lehen letra hartu, parametroak: katea eta kate banatzailea
erakTokena = strtok(sEsaldia, " ");
while (erakTokena != NULL)
{
if (boLehendabizikoa)
{
sEmaitza[0] = erakTokena[0]; // hitzaren lehen letra
sEmaitza[1] = '.'; // puntua
sEmaitza[2] = '\0'; // null mugatzailea
boLehendabizikoa = false;
}
else
{
sLaguntzailea[0] = erakTokena[0]; // hurrengo hitzaren lehen letra
sLaguntzailea[1] = '.'; // puntua
sLaguntzailea[2] = '\0'; // null mugatzailea
strcat(sEmaitza, sLaguntzailea); // kateaketa
}
// hurrengo tokena eskuratu, parametroak: NULL eta kate banatzailea
erakTokena = strtok(NULL, " ");
}
}
// Katearen /0 karakterea ikusteko eta RETURN karakterea ikusteko
void KateaIkusi(const char sKatea[101])
{
printf("\n");
// sarrerako katea pantailaratu, bere luzera +1 karaktere erakutsiz
for(int iKont = 0; iKont <= strlen(sKatea); iKont++)
{
printf("\t iKont=%d \t sKatea[iKont]=%c \t sKatea[iKont]=%d\n", iKont, sKatea[iKont], sKatea[iKont]);
}
printf("\n");
}
NAN-aren zenbaki zati 23 egiten da hondarra eskuratzeko
Zatiketa osoaren hondarra array lineal honetara ekarriz letra lortzen da, non behean arrayaren indizeak idatzi diren:
LETRA
T
R
W
A
G
M
Y
F
P
D
X
B
N
J
Z
S
Q
V
H
L
C
K
E
HONDARRA
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Adibidez, NAN-aren zenbakia 12345678 bada, zati 23 eginez zatiketa osoa egin ondoren ateratzen hondarra 14 da, horregatik dagokion letra Z da.
Ariketaren balizko emaitza ikusi, non karaktereen array konstante bat erabiltzen den, eta letra adierazteko char aldagai bat erabiltzen den. Emaitza den sNANa katea osatzeko bederatzigarren posizioan cLetra esleituko da eta azkena den hamargarren posizioan \0 karaktere-mugatzailea.
Bestela, zifren katea eta letraren karakterea kateatzeko sprintf() funtzio aplika daiteke, oso erraz ulertzen da printf() funtzioak pantailan idatziko zukeena helburuko katean jasotzen du sprintf() funtzioak. Gure kasuan, honela idatziko litzateke sprintf(sNANa, "%s%c", sZifrak, cLetra) non bilatzen dugun emaitza sNANa katea den.
/* Ariketa-53a_NANarenLetra: karakterek gordetzen dituen arraya */
// Karaktere-kateak '\0' markaz bukatzen diren arrayak dira C lengoaian.
// NAN baten zifrak teklatuaren bitartez jaso kate batean eta
// programak letra kalkulatu ondoren, NAN osoa pantailaratuko du.
// Letra adierazteko cLetra karakterea erabiliko da.
#include <stdio.h>
#include <string.h> // strlen() eta strcpy() funtzioetarako
#include <ctype.h> // isdigit() funtziorako
#include <conio.h> // getch() funtziorako
#define I_ZATITZAILEA 23
#define FALSE 0
const char acNANarenLETRA[I_ZATITZAILEA] =
{
'T', // 0
'R', // 1
'W', // 2
'A', // 3
'G', // 4
'M', // 5
'Y', // 6
'F', // 7
'P', // 8
'D', // 9
'X', // 10
'B', // 11
'H', // 12
'J', // 13
'Z', // 14
'S', // 15
'Q', // 16
'V', // 17
'H', // 18
'L', // 19
'C', // 20
'K', // 21
'E' }; // 22
char cLetraLortu(const char *);
int main()
{
char sZifrak[9]; // 8 digitu + null mugatzailea
char sNANa[10]; // 8 digitu + 1 letra + null mugatzailea
char cLetra;
int iKont;
printf("\n");
// for honen ordez katearen hasieraketa egin zitekeen, honela:
// char sZifrak[10] = "";
for (iKont=0; iKont < 8; iKont++)
sZifrak[iKont] = '\0';
iKont = 0;
printf(" NANren zortzi zifrak eman: ");
do
{
do
sZifrak[iKont] = getche();
while (isdigit(sZifrak[iKont]) == FALSE);
printf("\n\t iKont=%d \t datua: |%s|", iKont, sZifrak);
iKont++;
} while (strlen(sZifrak) != 8);
printf("\n");
cLetra = cLetraLortu(sZifrak);
printf("\n\t cLetra = |%c|", cLetra);
printf("\n\t strlen(sZifrak) = |%d| \t sZifrak = |%s|", strlen(sZifrak), sZifrak);
// sprintf(sNANa, "%s%c", sZifrak, cLetra);
strcpy(sNANa, sZifrak);
sNANa[8] = cLetra;
sNANa[9] = '\0';
printf("\n\t strlen(sNANa) = |%d| \t sNANa = |%s|", strlen(sNANa), sNANa);
printf("\n\n NAN = %s\n", sNANa);
printf("\n Edozein tekla sakatu exekuzioa amaitzeko... ");
getch();
printf("\n");
return 0;
}
char cLetraLortu(const char *sZifrak)
{
long liNANzenbakia;
sscanf(sZifrak, "%ld", &liNANzenbakia);
int iHondarra = liNANzenbakia % I_ZATITZAILEA;
return acNANarenLETRA[iHondarra];
}
Ariketaren balizko emaitza ikusi, non karaktereen array konstante bat erabiltzen den eta letra adierazteko sLetra[2] katea erabiltzen den. Emaitza den katea eskuratzeko kateaketaren strcat() funtzioa aplikatuko da.
/*Ariketa-53b_NANarenLetra: karakterek gordetzen dituen arraya */
// Karaktere-kateak '\0' markaz bukatzen diren arrayak dira C lengoaian.
// NAN baten zifrak teklatuaren bitartez jaso kate batean eta
// programak letra kalkulatu ondoren, NAN osoa pantailaratuko du.
// Letra adierazteko sLetra[2] katea erabiliko da.
#include <stdio.h>
#include <string.h> // strlen(), strcpy() eta strcat() funtzioetarako
#include <ctype.h> // isdigit() funtziorako
#include <conio.h> // getch() funtziorako
#define I_ZATITZAILEA 23
#define FALSE 0
const char acNANarenLETRA[I_ZATITZAILEA] =
{
'T', // 0
'R', // 1
'W', // 2
'A', // 3
'G', // 4
'M', // 5
'Y', // 6
'F', // 7
'P', // 8
'D', // 9
'X', // 10
'B', // 11
'H', // 12
'J', // 13
'Z', // 14
'S', // 15
'Q', // 16
'V', // 17
'H', // 18
'L', // 19
'C', // 20
'K', // 21
'E' }; // 22
void LetraLortu(const char *sZifrak, char *sLetra);
int main()
{
char sZifrak[9] = ""; // 8 digitu + null mugatzailea
char sNANa[10]; // 8 digitu + 1 letra + null mugatzailea
int iKont;
char sLetra[2]; // 1 letra + null mugatzailea
printf("\n");
iKont = 0;
printf(" NANren zortzi zifrak eman: ");
do
{
do
sZifrak[iKont] = getche();
while (isdigit(sZifrak[iKont]) == FALSE);
printf("\n\t iKont=%d \t datua: |%s|", iKont, sZifrak);
iKont++;
} while (strlen(sZifrak) != 8);
printf("\n");
LetraLortu(sZifrak, sLetra);
printf("\n\t strlen(sZifrak) = |%d| \t sZifrak = |%s|", strlen(sZifrak), sZifrak);
printf("\n\t strlen(sLetra) = |%d| \t sLetra = |%s|", strlen(sLetra), sLetra);
strcpy(sNANa, sZifrak);
strcat(sNANa, sLetra);
printf("\n\t strlen(sNANa) = |%d| \t sNANa = |%s|", strlen(sNANa), sNANa);
printf("\n\n NAN = %s\n", sNANa);
printf("\n Edozein tekla sakatu exekuzioa amaitzeko... ");
getch();
printf("\n");
return 0;
}
void LetraLortu(const char *sZifrak, char *sLetra)
{
long liNANzenbakia;
sscanf(sZifrak, "%ld", &liNANzenbakia);
int iHondarra = liNANzenbakia % I_ZATITZAILEA;
sLetra[0] = acNANarenLETRA[iHondarra];
sLetra[1] = '\0';
}