25. januar 2001 - 10:48
#5
Jeg kunne ikke lige finde referencen, men her er mit eksempel fra den gang (det kører under TC++ 3.0, som også er til DOS):
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ESC 0x1B
#define ENTER 0xD
#define DEL 0xEF53
#define BACKTAB 0x8
#define LEFT 0xEF4B
#define RIGHT 0xEF4D
#define false 0
#define true 1
typedef struct
{
char navn[21];
int lavkarakter, hoejkarakter;
void init(char *nNavn = \"\", int nLav = 0, int nHoej = 0)
{ sprintf(navn, \"%.*s\", sizeof(navn)-1, nNavn);
lavkarakter = nLav;
hoejkarakter = nHoej;
} // init
} defElev;
FILE *datFil;
int laeschar(char *streng, int lenStreng, int kunNum = false);
int laesnum(int& Num);
int laesElevOpl(defElev &elev, int nr);
/* ---------------------------- HOVED PROGRAM ----------------------- */
int main(void)
{
defElev elev, gemElev, gnmElev;
int antalElever, tast;
FILE *datFil;
clrscr();
// Den simple metode: l‘s igennem og vis/ret - ved sidste check for om
// ny skal tilf›jes. Da .DAT filen jo indeholder fast-l‘ngde poster, kan
// man vha. fseek rent faktisk placere sig p† en bestemt post hvis man vil.
datFil = fopen(\"dat_ex.dat\", \"a+b\");
if (datFil == NULL)
{
cprintf(\"FEJL: Filen \\\'dat_ex.dat\\\' kunne IKKE †bnes/dannes.\\r\\n\"
\"Programmet afbrudt.\\r\\n\");
return 1;
};
// Klar til at genneml›be evt. eksisterende elever.
gnmElev.init(\"Gennemsnit\");
antalElever = 0;
while (fseek(datFil, antalElever * sizeof(elev), SEEK_SET) == 0
&& fread(&elev, sizeof(elev), 1, datFil) == 1)
{
gemElev = elev;
antalElever++;
tast = laesElevOpl(elev, antalElever);
if (tast == ESC)
{
gnmElev.lavkarakter += gemElev.lavkarakter;
gnmElev.hoejkarakter += gemElev.hoejkarakter;
continue;
};
gnmElev.lavkarakter += elev.lavkarakter;
gnmElev.hoejkarakter += elev.hoejkarakter;
// Opdat‚r ‘ndret elev post. (antalElever optalt.)
if (fseek(datFil, (antalElever-1) * sizeof(elev), SEEK_SET) != 0
|| fwrite(&elev, sizeof(elev), 1, datFil) != 1)
{
cprintf(\"FEJL: Rettet post kunne IKKE genskrives.\\r\\n\"
\"Programmet afbrudt.\\r\\n\");
fflush(datFil);
fclose(datFil);
return 2;
};
}; // Genneml›b filen.
// EOF n†et - l‘s \"tom\" elev og gentag indtil ESC trykkes.
do
{
elev.init();
if (laesElevOpl(elev, antalElever) == ENTER)
{
if (fseek(datFil, antalElever *sizeof(elev), SEEK_SET) != 0
|| fwrite(&elev, sizeof(elev), 1, datFil) != 1)
{
cprintf(\"FEJL: Rettet post kunne IKKE genskrives.\\r\\n\"
\"Programmet afbrudt.\\r\\n\");
fflush(datFil);
fclose(datFil);
return 3;
};
antalElever++;
gnmElev.lavkarakter += elev.lavkarakter;
gnmElev.hoejkarakter += elev.hoejkarakter;
}
else
break;
} while (true);
// Luk filen.
fflush(datFil);
fclose(datFil);
// Udskriv gennemsnit.
if (antalElever > 0)
cprintf(\"\\r\\n\\r\\n\"
\"Der var i alt %d elever i filen med f›lgende gennemsnit:\\r\\n\"
\"Laveste karakter : %d\\r\\n\"
\"H›jeste karakter : %d\\r\\n\",
antalElever, gnmElev.lavkarakter / antalElever,
gnmElev.hoejkarakter / antalElever);
else
cprintf(\"\\r\\nDer er INGEN elever i filen.\\r\\n\");
return 0;
} // main
/* --------------------------------- ELEV ------------------------------ */
int laesElevOpl(defElev &elev, int nr)
{
char inputChar[sizeof(elev.navn)];
int inputNum;
char tast;
cprintf(\"\\r\\nFor elev nr. %d findes f›lgende oplysninger:\", nr);
// Navn
cprintf(\"\\r\\nElevens navn er : %s\\r\\n\", elev.navn);
cprintf(\"Indtast evt. nyt navn : \");
sprintf(inputChar, \"%.*s\", sizeof(inputChar)-1, elev.navn);
do
{
if (laeschar(inputChar, sizeof(inputChar)) == ESC)
return ESC;
if (strlen(inputChar) == 0)
cprintf(\"\\a FEJL: Elev navn SKAL indtastes.\\r\\n\");
else
break;
} while (true);
sprintf(elev.navn, \"%-*.*s\", sizeof(elev.navn)-1, sizeof(elev.navn)-1,
inputChar);
// Laveste karakter.
cprintf(\"\\r\\nElevens laveste karakter nu : %d\\r\\n\", elev.lavkarakter);
inputNum = elev.lavkarakter;
do
{
cprintf(\"Indtast ny laveste karakter : \");
if (laesnum(inputNum) == ESC)
return ESC;
if (inputNum != 0 && inputNum != 3 && inputNum != 5
&& inputNum != 6 && inputNum != 7 && inputNum != 8
&& inputNum != 9 && inputNum != 10 && inputNum != 11
&& inputNum != 13)
cprintf(\" FEJL: Ugyldigt karakter - pr›v igen.\\r\\n\");
else
break;
} while (true);
elev.lavkarakter = inputNum;
// H›jeste karakter.
cprintf(\"\\r\\nElevens h›jeste karakter nu : %d\\r\\n\", elev.hoejkarakter);
inputNum = elev.hoejkarakter;
do
{
cprintf(\"Indtast ny h›jeste karakter : \");
if (laesnum(inputNum) == ESC)
return ESC;
if (inputNum != 0 && inputNum != 3 && inputNum != 5
&& inputNum != 6 && inputNum != 7 && inputNum != 8
&& inputNum != 9 && inputNum != 10 && inputNum != 11
&& inputNum != 13)
cprintf(\" FEJL: Ugyldigt karakter - pr›v igen.\\r\\n\");
else
break;
} while (true);
elev.hoejkarakter = inputNum;
// Alt l‘st.
return ENTER;
} // laesElevOpl
/* ---------------------------- INTERNT ------------------------------- */
int laeschar(char *streng, int lenStreng, int kunNum)
{
int tast;
int x, y, ofs;
// Helt simpelt ville v‘re at bruge gets - men den g†r i fejl, hvis man
// indtaster flere tegn end lovligt - eller ikke numeriske tegn, s† vi
// laver en simpel rutine i stedet for.
x = wherex(); y = wherey();
cprintf(\"%.*s\", lenStreng, streng);
gotoxy(x, y);
ofs = 0;
do
{
if ((tast = getch()) == 0)
tast = 0xEF00 + getch();
switch (tast)
{
case ESC : // Afbryd.
break;
case ENTER : // Accept‚r det som er indtastet indtil nu.
break;
case DEL : // Slet et tegn.
if (*(streng+ofs) != \'\\x0\')
{ // Inds‘tter automatisk \'\\x0\' til slut.
sprintf(streng+ofs, \"%.*s\", lenStreng-ofs+2,
streng+ofs+1);
cprintf(\"%.*s \", lenStreng-ofs+1, streng+ofs);
gotoxy(x, y);
};
break;
case LEFT :
case BACKTAB : // Hop en pos. tilbage.
if (ofs > 0)
{
ofs--;
gotoxy(--x, y);
};
break;
case RIGHT : // Hop en pos. frem.
if (*(streng+ofs) != \'\\x0\' && ofs + 1 < lenStreng)
{
ofs++;
gotoxy(++x, y);
};
break;
default : // Alt muligt andet. Giv fejl (beep) hvis for mange
// eller ugyldige tegn.
if (ofs > lenStreng
|| kunNum && (tast < \'0\' || tast > \'9\'))
cprintf(\"\\a\");
else
{ // Tast OK - inds‘t den.
*(streng+ofs) = tast;
ofs++; x++;
cprintf(\"%c\", tast);
};
break;
}; // Switch p† tast
} while (tast != ESC && tast != ENTER);
return tast;
} // laeschar
int laesnum(int &Num)
{
char numStreng[6]; // Int = max 65535, dvs 5 cifre + en til stop tegn = 6
sprintf(numStreng, \"%d\", Num);
if (laeschar(numStreng, sizeof(numStreng)-1, true) != ESC)
{
Num = atoi(numStreng);
return ENTER;
};
return ESC;
} // laesnum