Inhoudsopgave:
Video: How old school cassette tape drives worked 2024
Willekeurige bestandstoegang in C-programmering heeft niets te maken met willekeurige getallen. Integendeel, het bestand kan op elk punt her en der, en zelfs yon worden geraadpleegd. Dit type toegang werkt het beste wanneer het bestand is gestippeld met records van dezelfde grootte. Het begrip records roept structuren op die gemakkelijk naar een bestand kunnen worden geschreven en vervolgens afzonderlijk, selectief of allemaal tegelijk kunnen worden teruggehaald.
Terwijl uw programma de gegevens van een bestand leest, houdt het de positie bij van waaruit gegevens in het bestand worden gelezen. Een cursorpositie wordt behouden, zodat de locatie waar de code in een bestand leest of schrijft, niet verloren gaat.
Wanneer u een bestand voor het eerst opent, bevindt de cursorpositie zich aan het begin van het bestand, de eerste byte. Als u een record van 40 bytes in het geheugen leest, is de cursorpositie vanaf het begin 40 bytes. Als u leest tot het einde van het bestand, behoudt de cursorpositie die locatie ook.
Om de zaken verwarrend te houden, wordt de cursorpositie vaak een -bestandwijzer , genoemd, ook al is dit geen aanwijzervariabele of een BESTAND type aanwijzer. Het is gewoon de locatie binnen een bestand waar de volgende byte aan gegevens wordt gelezen.
U kunt rotzooien met de cursorpositie door verschillende interessante functies in C te gebruiken. Twee ervan zijn ftell () en rewind (). De functie ftell () retourneert de huidige cursorpositie die is gecompenseerd als een lange int-waarde. De functie rewind () verplaatst de cursor terug naar het begin van het bestand.
De while-lus in Tell en Rewind leest in records van de binding. DB-bestand. Op regel 28 retourneert de functie ftell () de cursorpositie. Als het groter is dan één invoer (wat betekent dat de tweede invoer is gelezen), wordt de cursorpositie teruggezet naar het begin van het bestand door de functie rewind () op regel 29.
TELLEN EN TERUGSPOELEN
# include # include #include int main () {struct entry {char actor [32]; int jaar; char title [32];}; struct entry obligatie; BESTAND * a007; int count = 0; a007 = fopen ("bond. db", "r"); if (! a007) {puts ("SPELER wint!"); exit (1);} while (fread (& bond, sizeof (struct entry), 1, a007)) {printf ("% st% dt% sn", obligatieacteur, obligatiejaar, obligatietitel); if (ftell (a007)> sizeof (struct entry)) rewind (a007); tel ++; als (aantal> 10) pauze;} fclose (a007); return (0);}
Om de juiste offset te bepalen, vergelijkt een if-statement het resultaat van de ftell () -functie en sizeof-operator op de structuurinvoer. Houd er rekening mee dat ftell () alleen een lange int-waarde retourneert, niet een specifiek aantal structuren.
De variabele telling, gedeclareerd en geïnitialiseerd op regel 14, houdt bij hoe vaak de while-lus wordt herhaald. Als dit niet het geval was, zou het programma eindeloos doorlopen. Dat is slecht. Dus wanneer de waarde van de telling groter is dan 10, breekt de lus en wordt het bestand gesloten en eindigt het programma.
Oefening 1 : Typ de broncode van Tell and Rewind in uw editor. Build en run om te zien hoe de ftell () en rewind () functies werken.
Een specifiek record zoeken
Wanneer een bestand alle dezelfde grootte bevat, kunt u de functie fseek () gebruiken om elk afzonderlijk item uit te pluizen. Het formaat voor fseek () is
fseek (handle, offset, whence);
handle is een bestandsingreep, een BESTAND-aanwijzer die een bestand vertegenwoordigt dat geopend is voor lezen. offset is het aantal bytes vanaf de begin-, eind- of huidige positie in een bestand. En wherece is een van de drie constanten: SEEK_SET, SEEK_CUR of SEEK_END voor respectievelijk het begin, de huidige positie of het einde van een bestand.
Zolang uw bestand records van een constante grootte bevat, kunt u fseek () gebruiken om een specifiek record uit te pluizen, zoals weergegeven in Een specifiek record in een bestand zoeken.
VIND EEN SPECIFIEK RECORD IN EEN BESTAND
# include # include # include int main () {struct entry {char actor [32]; int jaar; char title [32];}; struct entry obligatie; BESTAND * a007; a007 = fopen ("bond. db", "r"); if (! a007) {puts ("SPELER wint!"); exit (1);} fseek (a007, sizeof (struct entry) * 1, SEEK_SET); fread (& bond, sizeof (struct entry), 1, a007); printf ("% st% dt% sn", obligatieacteur, obligatiejaar, obligatie titel); fclose (A007); return (0);}
De code die wordt weergegeven in Een specifiek record in een bestand zoeken is weer redelijk vergelijkbaar met de code die wordt getoond in listing 22-9. De grote toevoeging is de functie fseek (), weergegeven op regel 21. Deze stelt de cursorpositie zo in dat de fread () -functie die volgt (zie regel 22) een specifiek record binnen de database leest.
Op regel 21 onderzoekt de functie fseek () het bestand dat wordt vertegenwoordigd door handle a007. De offset wordt berekend door de grootte van de ingangsstructuur te vermenigvuldigen.
Net als bij een array levert het vermenigvuldigen van die grootte met 1 de seconde record op in het bestand; vermenigvuldig de waarde met 0 (of geef 0 op in de functie) om de eerste record te lezen. De constante SEEK_SET zorgt ervoor dat fseek () vanaf het begin van het bestand begint te kijken.
Het netto-effect van de code is dat het tweede record in de obligatie. DB-bestand wordt weergegeven.
Oefening 2: Typ de broncode in Zoek een specifiek record in een bestand. Bouw en voer uit om het tweede record in het bestand te zien.