[Ez da ikasi behar, nik ez dut galdetuko]
| ZER DAKIDAN: Fitxategiak eta arrayak antzekoak dira datu-mota bereko hainbat elementu gordetzen dituztelako. Algoritmo batzuk errazagoak dira arrayetan fitxategietan baino; adibidez, errazago sailkatzen da array bat fitxategi bat baino. Horregatik... ZER IKASIKO DUDAN: ...horregatik, fitxategiko elementu guztiak array laguntzaile batera eramango ditut, arrayan elementuak sailkatuko ditut 11. jarduera | Array bat sailkatu/ordenatu kasuan egin nuen bezala, eta, bukatzeko, arrayaren informazio ordenatua hasierako fitxategian gordeko dut. |
Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, erregistroen fitxategi bat daukagu eta erregistroen eremu bat fNota izendatu da. Programa honen helburua da fitxategia sailkatzea fNota eremuaren arabera, nota txikitenetik nota handienera fitxategia ordenatzea, alegia.
Sailkatze lana oso zaila da fitxategian burutzea, baina array batean egingarria da 11. jarduera | Array bat sailkatu/ordenatu adibidean erakutsi zen bezal. Beraz, jarraian erakusten den programan, lanen sekuentzia hau izango da: fitxategitik arrayra > arraya ordenatu > arraytik fitxategira.
eta horregatik Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, erregistroen fitxategi bat daukagu eta erregistroen eremu bat fNota izendatu da. Programa honen helburua da fitxategia sailkatzea fNota eremuaren arabera, nota txikienetik nota handienera fitxategia ordenatzea, alegia.
Erakusten den programa honetan fitxategiaren existentzia ez da frogatzen baina FitxategiaIkusi() funtzioan ezin bada fitxategia ireki programa bukatutzat ematen da. Emandako izena duen fitxategirik bada bere edukia pantailaratzen da eta liZenbatElementu dituen elementuen kopurua kalkulatzen da, liZenbatElementu aldagaiak hartzen duen balioaren arabera erabaki hauek hartuko dira:
- Baldin eta liZenbatElementu handiagoa bada arrayaren neurria baino, mezu bat erakutsiko da pantailan eta aukera ematen zaio erabiltzaileari beste fitxategi baten izena aukeratu dezan.
- Fitxategiko elementu guztiak arrayan sar badaitezke urratsak hauek izango dira:
- Zehaztutako fitxategiaren edukia array laguntzaile batean gorde
- Array laguntzailea fNota arabera sailkatu
- Array laguntzailea ordenatuaren edukia jatorrizko fitxategira kopiatu aurreko informazioa galduz
/* Ariketa-91_Fitxategien_16_algoritmoa: sailkatu */
// Erregistroen fitxategi bat ordenatuko da fNota eremuaren
// arabera. Horretarako, fitxategiko edukia array laguntzaile
// batera eramango da sailkatze lana arrayan egiteko da, arraya
// ordenaturik dagoela bere informazioa fitxategian gordeko da.
#include <stdio.h>
#include <stdlib.h> // exit() funtziorako
#include <string.h> // strcspn() funtziorako
#define GOIMUGA 9
#define FITX_IZEN_MAX 120 // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define DATU_IZEN_MAX 72 // ikaslearen izena gordetzeko 71 karaktere gehi null mugatzailea
#define sBIDEA "C:\\Tokia\\"
// struct edo erregistroa definitzen ikasle baten datuak gordetzeko
struct tstFitxa
{
char sIzenDeiturak[DATU_IZEN_MAX];
int iDeialdia;
float fNota;
};
void FitxategiaIkusi(const char sFitxIzen[]);
void FitxategitikBektoreaBete(const char sFitxIzen[],
struct tstFitxa astZerren[],
long *liLuzera);
void BektoretikFitxategiaBete(const char sFitxIzen[],
struct tstFitxa astZerren[],
long liLuzera);
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera);
void NotazOrdenatu(struct tstFitxa astZerren[], long liLuzera);
long liFitxategiarenEsparrua(const char sFitxIzen[]);
int main()
{
char sFitxIzenLabur[FITX_IZEN_MAX];
char sFitxIzen[FITX_IZEN_MAX];
long liZenbatElementu, liLuzera;
struct tstFitxa astZerren[GOIMUGA];
do
{
printf("Fitxategia existitzen da eta datuak ditu (adibidez C:\\Tokia\\Ikasleak.DAT)\n");
printf("Fitxategiaren izen laburra eman ('Ikasleak' adibidez): ");
gets(sFitxIzenLabur);
strcpy(sFitxIzen, sBIDEA);
strcat(sFitxIzen, sFitxIzenLabur);
strcat(sFitxIzen, ".dat");
printf("Fitxategiaren izen osoa: >>>%s<<<\n\n", sFitxIzen);
FitxategiaIkusi(sFitxIzen);
liZenbatElementu = liFitxategiarenEsparrua(sFitxIzen);
printf("Fitxategiaren elementuen kopurua %ld da eta bektoreak %d elementu onartzen ditu\n", liZenbatElementu, GOIMUGA+1);
if (liZenbatElementu > GOIMUGA+1)
{
printf("'%s' fitxategia handiegia da programa honenzat\n", sFitxIzen);
printf("Beste fitxategi-izen batekin saiatu!\n\n");
}
} while (liZenbatElementu > GOIMUGA+1);
FitxategitikBektoreaBete(sFitxIzen, astZerren, &liLuzera);
printf("Bektorea ordenatu baino lehen\n");
BektoreaIkusi(astZerren, liLuzera);
NotazOrdenatu(astZerren, liLuzera);
printf("Bektorea ordenaturik\n");
BektoreaIkusi(astZerren, liLuzera);
BektoretikFitxategiaBete(sFitxIzen, astZerren, liLuzera);
FitxategiaIkusi(sFitxIzen);
printf("Programa bukatzera doa\n");
return 0;
}
// fitxategiaren edukia ikusteko funtzioa
void FitxategiaIkusi(const char sFitxIzen[])
{
FILE *fFitxategia;
struct tstFitxa stElem;
fFitxategia = fopen(sFitxIzen, "rb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'FitxategiaIkusi()' funtzioan \a\n", sFitxIzen);
exit(1);
}
printf("Fitxategiaren edukia:\n");
while (fread(&stElem, sizeof(struct tstFitxa), 1, fFitxategia))
{
printf("%-50s %10d %15.2f\n", stElem.sIzenDeiturak,
stElem.iDeialdia,
stElem.fNota);
}
printf("\n");
fclose(fFitxategia);
}
// fitxategitik abiatuta bektorea betetzeko funtzioa
void FitxategitikBektoreaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long *liLuzera)
{
FILE *fFitxategia;
fFitxategia = fopen(sFitxIzen, "rb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'FitxategitikBektoreaBete()' funtzioan \a\n", sFitxIzen);
return;
}
*liLuzera = 0;
while (*liLuzera < GOIMUGA && fread(&astZerren[*liLuzera], sizeof(struct tstFitxa), 1, fFitxategia))
{
(*liLuzera)++;
}
(*liLuzera)--;
fclose(fFitxategia);
}
// bektoretik abiatuta fitxategia betetzeko funtzioa
void BektoretikFitxategiaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long liLuzera)
{
FILE *fFitxategia;
fFitxategia = fopen(sFitxIzen, "wb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'BektoretikFitxategiaBete()' funtzioan \a\n", sFitxIzen);
return;
}
for (long i = 0; i <= liLuzera; i++)
{
fwrite(&astZerren[i], sizeof(struct tstFitxa), 1, fFitxategia);
}
fclose(fFitxategia);
}
// bektorea ikusteko funtzioa
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera)
{
printf("Arrayaren edukia:\n");
for (long i = 0; i <= liLuzera; i++)
{
printf("%-50s %10d %15.2f\n", astZerren[i].sIzenDeiturak,
astZerren[i].iDeialdia,
astZerren[i].fNota);
}
printf("\n");
}
// bektore baten ordenazioa notaren arabera, aukeraketa metodoaren bidez
void NotazOrdenatu(struct tstFitxa astZerren[], long liLuzera)
{
for (long k = 0; k < liLuzera; k++)
{
long liPosMin = k;
struct tstFitxa rdMin = astZerren[k];
for (long j = k + 1; j <= liLuzera; j++)
{
if (rdMin.fNota > astZerren[j].fNota)
{
rdMin = astZerren[j];
liPosMin = j;
}
}
// trukatu
astZerren[liPosMin] = astZerren[k];
astZerren[k] = rdMin;
}
}
// fitxategiaren tamaina lortzeko funtzioa
long liFitxategiarenEsparrua(const char sFitxIzen[])
{
FILE *fFitxategia;
long liZenbatElem;
fFitxategia = fopen(sFitxIzen, "rb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'liFitxategiarenEsparrua()' funtzioan \a\n", sFitxIzen);
return 0;
}
fseek(fFitxategia, 0L, SEEK_END);
liZenbatElem = ftell(fFitxategia) / sizeof(struct tstFitxa);
fclose(fFitxategia);
return liZenbatElem;
}
Gauza bera egin daiteke erregistroen bi eremuen araberako sailkatze-lana burutuz. Adibidez, demagun erregistroen fitxategia byDeialdia eremuaren arabera sailkatu nahi dela nagusiki, eta byDeialdia eremuaren balioak berdinak direnean sIzenDeiturak eremuaren arabera sailkatuko dela.
Ikus dezagun adibidez ondoko erregistroan oinarritutako fitxategia bat nola sailkatzen den bi eremuen informazioaren arabera. Sailkatze-lana DeialdizEtaNotazOrdenatu() funtzioan egiten da, zeinek array bat ordenatzen duen:
/* Ariketa-91_Fitxategien_16b_algoritmoa: bi eremuen arabera sailkatu */
// Erregistroen fitxategi bat ordenatuko da byDeialdia eremuaren
// eta fNota eremuaren arabera. Horretarako, fitxategiko edukia
// array laguntzaile batera eramango da sailkatze lana arrayan
// eginez (byDeialdia ordenatze-ezaugarri nagusia da eta horrren
// berdintasunik izatean fNota ordenatze-ezaugarri erabiliko da).
// Arraya ordenatuaren informazioa fitxategian gordeko da.
#include <stdio.h>
#include <string.h> // strcmp() funtziorako
#include <stdlib.h> // exit() funtziorako
#define GOIMUGA 9
#define FITX_IZEN_MAX 120 // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define DATU_IZEN_MAX 72 // ikaslearen izena gordetzeko 71 karaktere gehi null mugatzailea
#define sBIDEA "C:\\Tokia\\"
// struct edo erregistroa definitzen ikasle baten datuak gordetzeko
struct tstFitxa
{
char sIzenDeiturak[DATU_IZEN_MAX];
int iDeialdia;
float fNota;
};
void FitxategiaIkusi(const char sFitxIzen[]);
void FitxategitikBektoreaBete(const char sFitxIzen[],
struct tstFitxa astZerren[],
long *liLuzera);
void BektoretikFitxategiaBete(const char sFitxIzen[],
struct tstFitxa astZerren[],
long liLuzera);
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera);
void DeialdizEtaNotazOrdenatu(struct tstFitxa astZerren[], long liLuzera);
long liFitxategiarenEsparrua(const char sFitxIzen[]);
int main()
{
char sFitxIzenLabur[FITX_IZEN_MAX];
char sFitxIzen[FITX_IZEN_MAX];
long liZenbatElementu, liLuzera;
struct tstFitxa astZerren[GOIMUGA];
do
{
printf("Fitxategia existitzen da eta datuak ditu (adibidez C:\\Tokia\\Ikasleak.DAT)\n");
printf("Fitxategiaren izen laburra eman ('Ikasleak' adibidez): ");
gets(sFitxIzenLabur);
strcpy(sFitxIzen, sBIDEA);
strcat(sFitxIzen, sFitxIzenLabur);
strcat(sFitxIzen, ".dat");
printf("Fitxategiaren izen osoa: >>>%s<<<\n\n", sFitxIzen);
FitxategiaIkusi(sFitxIzen);
liZenbatElementu = liFitxategiarenEsparrua(sFitxIzen);
printf("Fitxategiaren elementuen kopurua %ld da eta bektoreak %d elementu onartzen ditu\n", liZenbatElementu, GOIMUGA+1);
if (liZenbatElementu > GOIMUGA+1)
{
printf("'%s' fitxategia handiegia da programa honenzat\n", sFitxIzen);
printf("Beste fitxategi-izen batekin saiatu!\n\n");
}
} while (liZenbatElementu > GOIMUGA+1);
FitxategitikBektoreaBete(sFitxIzen, astZerren, &liLuzera);
printf("Bektorea ordenatu baino lehen\n");
BektoreaIkusi(astZerren, liLuzera);
DeialdizEtaNotazOrdenatu(astZerren, liLuzera);
printf("Bektorea ordenaturik\n");
BektoreaIkusi(astZerren, liLuzera);
BektoretikFitxategiaBete(sFitxIzen, astZerren, liLuzera);
FitxategiaIkusi(sFitxIzen);
printf("Programa bukatzera doa\n");
return 0;
}
// fitxategiaren edukia ikusteko funtzioa
void FitxategiaIkusi(const char sFitxIzen[])
{
FILE *fFitxategia;
struct tstFitxa stElem;
fFitxategia = fopen(sFitxIzen, "rb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'FitxategiaIkusi()' funtzioan \a\n", sFitxIzen);
exit(1);
}
printf("Fitxategiaren edukia:\n");
while (fread(&stElem, sizeof(struct tstFitxa), 1, fFitxategia))
{
printf("%-50s %10d %15.2f\n", stElem.sIzenDeiturak,
stElem.iDeialdia,
stElem.fNota);
}
printf("\n");
fclose(fFitxategia);
}
// fitxategitik abiatuta bektorea betetzeko funtzioa
void FitxategitikBektoreaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long *liLuzera)
{
FILE *fFitxategia;
fFitxategia = fopen(sFitxIzen, "rb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'FitxategitikBektoreaBete()' funtzioan \a\n", sFitxIzen);
return;
}
*liLuzera = 0;
while (*liLuzera < GOIMUGA && fread(&astZerren[*liLuzera], sizeof(struct tstFitxa), 1, fFitxategia))
{
(*liLuzera)++;
}
(*liLuzera)--;
fclose(fFitxategia);
}
// bektoretik abiatuta fitxategia betetzeko funtzioa
void BektoretikFitxategiaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long liLuzera)
{
FILE *fFitxategia;
fFitxategia = fopen(sFitxIzen, "wb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'BektoretikFitxategiaBete()' funtzioan \a\n", sFitxIzen);
return;
}
for (long i = 0; i <= liLuzera; i++)
{
fwrite(&astZerren[i], sizeof(struct tstFitxa), 1, fFitxategia);
}
fclose(fFitxategia);
}
// bektorea ikusteko funtzioa
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera)
{
printf("Arrayaren edukia:\n");
for (long i = 0; i <= liLuzera; i++)
{
printf("%-50s %10d %15.2f\n", astZerren[i].sIzenDeiturak,
astZerren[i].iDeialdia,
astZerren[i].fNota);
}
printf("\n");
}
// bektore baten ordenazioa notaren arabera, aukeraketa metodoaren bidez
void DeialdizEtaNotazOrdenatu(struct tstFitxa astZerren[], long liLuzera)
{
for (long k = 0; k < liLuzera; k++)
{
long liPosMin = k;
struct tstFitxa rdMin = astZerren[k];
for (long j = k+1; j <= liLuzera; j++) // ordenatu gabekoen artean minimoa non dagoen zehaztu
{
if (
(rdMin.iDeialdia > astZerren[j].iDeialdia) ||
(
(rdMin.iDeialdia == astZerren[j].iDeialdia) && // rdMin.iDeialdia berdina denean eta...
(strcmp(rdMin.sIzenDeiturak, astZerren[j].sIzenDeiturak) > 0) // rdMin.sIzenDeiturak handiagoa denean...
)
)
{
rdMin = astZerren[j];
liPosMin = j;
}
}
// trukatu
astZerren[liPosMin] = astZerren[k];
astZerren[k] = rdMin;
}
}
// fitxategiaren tamaina lortzeko funtzioa
long liFitxategiarenEsparrua(const char sFitxIzen[])
{
FILE *fFitxategia;
long liZenbatElem;
fFitxategia = fopen(sFitxIzen, "rb");
if (!fFitxategia)
{
printf("Errorea '%s' fitxategia irekitzean 'liFitxategiarenEsparrua()' funtzioan \a\n", sFitxIzen);
return 0;
}
fseek(fFitxategia, 0L, SEEK_END);
liZenbatElem = ftell(fFitxategia) / sizeof(struct tstFitxa);
fclose(fFitxategia);
return liZenbatElem;
}
|
iruzkinik ez:
Argitaratu iruzkina