ZER DAKIDAN: Ariketa 49 | Kate bat hartu eta pantailaratu artikuluan ikasi nuen kate bat teklatuz irakurtzen. Helbidearen kontzeptua ezagutzen dudanez beste urrats bat eman dezaket, bi kate jarraian irakurtzea. ZER IKASIKO DUDAN: Bi karaktere-kate teklatutik irakurtzean gerta daiteke bigarrenak lehen zapaltzea baldin eta luzeegia bada. |
Kate pare bat irakurtzean gerta daiteke kate batek bestearen posizioak hartzea
Kate pare bat irakurtzean gerta daiteke kate batek bestearen posizioak hartzea, bi aldagaiak memorian hurbil kokaturik egonez gero.
Lehen katea irakurtzeko gets(sKate1) egiten da kontrolatuz neurritik kanpo ez doala. Lehen irakurketaren aginduak hauek dira:
do { printf(" Lehen katea eman (adibidez: 0123345): "); gets(sKate1); if (strlen(sKate1) >= MAXIMOA) printf(" Gehienez %d karaktereko katea behar da \n", MAXIMOA-1); } while (strlen(sKate1) >= MAXIMOA); printf(" sKate1=|%s| \n", sKate1);
Bigarren katea modu beretsuan irakurtzen da gets(sKate2) eginez eta berdin kontrolatzen da neurritik kanpo ez doakigula. Bigarren irakurketaren aginduak hauek dira:
do { gets(sKate2); if (strlen(sKate2) >= MAXIMOA) { printf(" Gehienez %d karaktereko katea behar da ", MAXIMOA-1); printf("\n Bigarren katea eman (adibidez, 543210): "); } } while (strlen(sKate2) >= MAXIMOA);
Kontrol bi horiek ez dira nahiko Ariketa-52a_KateBatZapalduta.cbp programan ikus daitekeen bezala.
Programa hau exekutatu eta aztertu, ezer baino lehen ikusi sKate1 eta sKate2 aldagaien kokapenak memorian.
Lehenik, sKate1 aldagaia irakurri dugu bere neurria zainduz. Gero, sKate2 aldagaia irakurri dugu datu luzeegia emanez, programak hori kontrolatzen du eta errepikarazi egingo digu, sKate2 bigarrenez ondo irakurtzean aurrera egingo du programak, baina azken emaitzan ikus daiteke sKate1 aldagaia kalteturik geratu dela.
/* Ariketa-52a_KateBatZapalduta: kate batek beste katearen posizioak har ditzake. */ // Nahiz eta do-while honen bitartez ziurtatzen dugun sKate2 mugaren barruan dagoen: // while (strlen(sKate2) >= MAXIMOA); // Ordurako kaltea egina egon daiteke, hots, luzeegia den datu bat sartu izan bada // sKate1 aldagaiaren hasierako posizioak bereganatu dituelako sKate2 kateak. #include <stdio.h> #include <string.h> // gets() eta strlen() funtzioetarako #include <conio.h> // getch() funtziorako #define MAXIMOA 7 // katea mugatzeko konstantea, // 6 karaktere + null mugatzailea int main() { char sKate2[MAXIMOA]; // 6 karaktere + null gordetzeko katea char sKate1[MAXIMOA]; // 6 karaktere + null gordetzeko katea printf("\n ------------------------------------------------------------------------------\n"); printf("\n sKate2-ren hasierako helbidea: %d", (int)sKate2); printf("\n sKate2-ren azkeneko helbidea: %d <--- bere muga gainditzean...", (int)&sKate2[MAXIMOA-1]); printf("\n sKate1-ren hasierako helbidea: %d <--- posizio hauek hartuko ditu", (int)sKate1); printf("\n sKate1-ren azkeneko helbidea: %d <--- posizio hauek hartuko ditu\n", (int)&sKate1[MAXIMOA-1]); printf("\n Kontuz!!! sKate2 luzeegia bada, bere azken karaktereak"); printf("\n sKate1 aldagaiaren posizioetan kokatuko dira (\\0 karakterea ere)"); printf("\n Horregatik, arazoa ekiditeko, sKate2 katea karaktereka irakurriko dugu"); printf("\n\n ------------------------------------------------------------------------------\n"); printf("\n Karaktere kopuru maximoa %d izan arren, ondoko datuak eman...", MAXIMOA-1); printf("\n\n"); do { printf(" Lehen katea eman (adibidez: 012345): "); gets(sKate1); if (strlen(sKate1) >= MAXIMOA) printf(" Gehienez %d karaktereko katea behar da \n", MAXIMOA-1); } while (strlen(sKate1) >= MAXIMOA); printf(" sKate1=|%s| \n", sKate1); printf("\n Bigarren katea eman (adibidez, luzeegia den hau: ABCDEFGHIJ): "); do { gets(sKate2); if (strlen(sKate2) >= MAXIMOA) { printf(" sKate2=|%s| \n", sKate2); printf(" Gehienez %d karaktereko katea behar da ", MAXIMOA-1); printf("\n Bigarren katea eman (adibidez, 543210): "); } } while (strlen(sKate2) >= MAXIMOA); printf("\n Lehen katea sKate1=|%s|", sKate1); printf("\n Bigarren katea sKate2=|%s|", sKate2); printf("\n\n Edozein tekla sakatu exekuzioa amaitzeko... "); getch(); printf("\n\n"); return 0; }
Hauxe da programaren azalpena. Demagun sKate1 katearen edukia 012345 dela eta memoriako posizioak 6422297 eta 6422303 artekoak direla; demagun ere sKate2 katearen lehen irakurketaren edukia ABCDEFGHIJ dela eta memoriako posizioak 6422290 eta 6422296 artekoak direla. Memorian honelako zerbait gertatzen da, non 6422297 posiziotik 6422297 posiziora dauden karaktereak sKate2 katearenak izango diren:
Indizeak sKate1[] &sKate1[] sKate2[] &sKate2[] ======== ======== ========= ======== ========= 0 A 6422290 1 B 6422291 2 C 6422292 3 D 6422293 4 E 6422294 5 F 6422295 6 G 6422296 ----- --------- --------- -------- -------- 0 |
Baina, programak ez du onartuko sKate2 katearen ABCDEFGHIJ lehen irakurketa luzeegia delako (dagoeneko sKate1 katea aldatu du sKate2 kateak). Horregatik, sKate2 katearen bigarren irakurketa egitean 543210 ematean memorian hau biltegituko da:
Indizeak sKate1[] &sKate1[] sKate2[] &sKate2[] ======== ======== ========= ======== ========= 0 5 6422290 1 4 6422291 2 3 6422292 3 2 6422293 4 1 6422294 5 0 6422295 6 \0 6422296 ----- --------- --------- -------- -------- 0 H 6422297 1 I 6422298 2 J 6422299 3 \0 6422300 4 4 6422301 5 5 6422302 6 \0 6422303 |
Hauxe da Ariketa-52a_KateBatZapalduta programaren exekuzio bat goiko datu horiek emanez. Jakina da ordenadore batetik bestera sKate1 katearen eta sKate2 katearen helbideak desberdinak izango da:
Demagun zifrak ari garela irakurtzen. Programa hau exekutatu eta ikusi bi irakurketen arteko aldea, kate osoa irakurtzearena eta katea karaktereka irakurtzearena:
/* Ariketa-52b_KateBatZapalduta: kate batek beste katearen posizioak har ditzake. */ // Nahiz eta do-while honen bitartez ziurtatzen dugun sKate2 mugaren barruan dagoen: // while (strlen(sKate2) >= MAXIMOA); // Horregatik sKate2 katea karaktereka irakurriko dugu getche() funtzioaren bitartez. #include <stdio.h> #include <string.h> // strlen() funtziorako #include <conio.h> // getch() eta getche() funtzioetarako #include <ctype.h> // isdigit() funtziorako #define FALSE 0 #define MAXIMOA 7 // 6 karaktere + null mugatzailea int main() { char sKate2[MAXIMOA]=""; // 6 digitu + null mugatzailea char sKate1[MAXIMOA]=""; // 6 digitu + null mugatzailea char cKarak; int iKont; printf("\n\n ----------------------------------------------------------------------\n"); printf("\n sKate2-ren helbidea: %d <--- bere muga gainditzean...", (int)sKate2); printf("\n sKate1-ren helbidea: %d <--- posizio hauek hartuko ditu\n", (int)sKate1); printf("\n Kontuz!!! sKate2 luzeegia bada, bere azken karaktereak"); printf("\n sKate1 aldagaiaren posizioetan kokatuko dira"); printf("\n Horregatik, arazoa ekiditeko, sKate2 katea karaktereka irakurriko dugu"); printf("\n\n ----------------------------------------------------------------------\n"); printf("\n\n"); do { printf(" Lehen katea eman (adibidez: 012345): "); gets(sKate1); if (strlen(sKate1) >= MAXIMOA) printf(" Gehienez %d karaktereko katea behar da \n", MAXIMOA-1); } while (strlen(sKate1) >= MAXIMOA); printf("\t strlen(sKate1)=|%d| \t sKate1=|%s|", strlen(sKate1), sKate1); printf("\n"); printf("\n Gehienez %d zifra onartuko dira, lehenago amaitzeko lau hauetariko bat sartu:", MAXIMOA-1); printf("\n\t\t\t X"); printf("\n\t\t\t x"); printf("\n\t\t\t ."); printf("\n\t\t\t RETURN\n\t\t\t "); iKont = 0; do { do { cKarak = getche(); if ((isdigit(cKarak) == FALSE) && (cKarak != '\r') && (cKarak != '.') && (cKarak != 'X') && (cKarak != 'x')) printf("\n BERRIRO %d. zifra \t ", iKont); else if (cKarak != '\r') // RETURN karakterea ez gorde katean sKate2[iKont] = cKarak; } while ((isdigit(cKarak) == FALSE) && (cKarak != '\r') && (cKarak != '.') && (cKarak != 'X') && (cKarak != 'x')); if (iKont == MAXIMOA-1) sKate2[MAXIMOA-1] = '\0'; iKont++; if (cKarak != '\r') printf("\n\t iKont=%d \t datua: |%s| ", iKont-1, sKate2); else printf("\n\t iKont=%d \t datua: |%sRETURN| ", iKont-1, sKate2); } while ((cKarak != '\r') && (sKate2[iKont-1] != '.') && (sKate2[iKont-1] != 'X') && (sKate2[iKont-1] != 'x') && (iKont < MAXIMOA)); if ((sKate2[strlen(sKate2)-1] == '.') || (sKate2[strlen(sKate2)-1] == 'X') || (sKate2[strlen(sKate2)-1] == 'x')) sKate2[strlen(sKate2)-1] = '\0'; printf("\n\t strlen(sKate2)=%d \t sKate2=|%s|", strlen(sKate2), sKate2); printf("\n\t strlen(sKate1)=%d \t sKate1=|%s|", strlen(sKate1), sKate1); printf("\n\n Edozein tekla sakatu exekuzioa amaitzeko... "); getch(); printf("\n"); return 0; }
Aurreko ariketa interesgarria da, baina argi dago programazio konplexua duela. Kodea erraztu aldera, ekar dezagun gogora Ariketa 49 | Kate bat hartu eta pantailaratu artikuluan azaldu zen garrantzitsua den fgets(sKateBat, iGehienezZenbatKaraktere, stdin) funtzioa:
/* Ariketa-52c_KateBatZapalduta: kate batek beste katearen posizioak ez ditu hartuko. */ // Horregatik, fgets() funtzioa erabil daiteke zeinetan zenbat karaktere hartuko // diren zehaztu beharra dagoen. #include <stdio.h> #include <string.h> // fgets() eta strlen() funtzioetarako #include <conio.h> // getch() eta getche() funtzioetarako #define MAXIMOA 7 // katea mugatzeko konstantea, // 6 karaktere + null mugatzailea int main() { char sKate2[MAXIMOA]; // 6 karaktere + null gordetzeko katea char sKate1[MAXIMOA]; // 6 karaktere + null gordetzeko katea printf("\n\n ----------------------------------------------------------------------\n"); printf("\n sKate2-ren helbidea: %d <--- bere muga gainditzean...", (int)sKate2); printf("\n sKate1-ren helbidea: %d <--- posizio hauek hartuko ditu\n", (int)sKate1); printf("\n Kontuz!!! sKate2 luzeegia bada, bere azken karaktereak"); printf("\n sKate1 aldagaiaren posizioetan kokatuko dira"); printf("\n Horregatik fgets(sKatea, iZenbat, stdin) funtzioa erabiliko dugu"); printf("\n\n ----------------------------------------------------------------------\n"); printf("\n Karaktere kopuru maximoa %d izan arren, ondoko datuak eman...", MAXIMOA-1); printf("\n\n"); printf(" Lehen katea eman (adibidez, luzeegia den hau 123456789): "); fgets(sKate1, MAXIMOA, stdin); if (sKate1[strlen(sKate1)-1] == '\n') // RETURN egotekotan azkena izango da sKate1[strlen(sKate1)-1] = '\0'; // RETURN karakterea kendu fflush(stdin); printf(" Lehen katea sKate1=|%s| %d karaktere", sKate1, (int)strlen(sKate1)); printf("\n\n"); printf(" Bigarrena sartu (adibidez, luzeegia den hau 9876543210): "); fgets(sKate2, MAXIMOA, stdin); if (sKate2[strlen(sKate2)-1] == '\n') // RETURN egotekotan azkena izango da sKate2[strlen(sKate2)-1] = '\0'; // RETURN karakterea kendu fflush(stdin); printf(" Bigarren katea sKate2=|%s| %d karaktere", sKate2, (int)strlen(sKate2)); printf("\n\n Edozein tekla sakatu exekuzioa amaitzeko... "); getch(); printf("\n"); return 0; }
|
iruzkinik ez:
Argitaratu iruzkina