Можно выполнять операции произвольного чтения и записи, используя систему буферизированного ввода-вывода, с помощью функции fseek(), устанавливающей текущую файловую позицию. Её прототип:
int fseek(FILE *fp, long число_байт, int начало);
где *fp – это указатель на файл, число_байт – это длинное целое, содержащее число байт от начала до позиции маркера, а начало – это одно из макроопределений:
Макроопределение
Смысл
SEEK_SET
Начало файла
SEEK_CUR
Текущая позиция
SEEK_END
Конец файла
Макроопределения есть целочисленные значения, причём SEEK_SET равен 0, SEEK_CUR 1, SEEK_END 2. Функция fseek() возвращает 0 в случае удачи или ненулевое значение в случае ошибки.
Чтение 234-ого байта из файла test.
int func(void)
{
FILE *fp;
if ((fp = fopen(“test”, “rb”) == NULL) {
printf(“Cannot open file.\n”);
exit(1); }
fseek(fp, 234L, 0);
return getc(fp);
}
Другой пример – программа, позволяющая просмотреть содержимое файла, как в ASCII, так и шестнадцатеричном формате.
#include <stdio.h>
#include <ctype.h>
#define SIZE 128
void display(int numread);
char buf[SIZE];
int main(int argc, char *argv[])
{
FILE *fp;
int sector, numread;
if(argc!=2) {
printf("Usage: dump filename");
return 1;
}
if((fp=fopen(argv[1], "rb"))==NULL) {
printf("Cannot open file.");
return 1;
}
do {
printf("Enter sector: ");
scanf("%d", §or);
if(sector >= 0) {
if(fseek(fp, sector*SIZE, SEEK_SET)) {
printf("seek error");
}
if((numread=fread(buf, 1, SIZE, fp))!=SIZE)
printf("EOF reached.");
display(numread);
}
}while(sector >= 0);
return 0;
}
void display(int numread)
{
int i, j;
for(i=0; i<numread/16; i++) {
for(j=0; j<16; j++)
printf("%3X", buf[i*16+j]);
printf(" ");
for(j=0; j<16; j++) {
if(isprint(buf[i*16+j]))
printf("%c",buf[i*16+j]);
else printf(".");
}
printf("\n");
}
}
Результат действия программы на файл с текстом программы:
Функция ferror( )
Функция ferror() используется для определения, привела ли выполненная операция к ошибке.
int ferror(FILE *fp);
Она возвращает истину, если в результате выполнения предыдущей операции произошла ошибка.
fprintf() и fscanf()
Помимо основных функций ввода-вывода, система буферизированного ввода-вывода содержит fprintf() и fscanf(). Данные функции ведут себя также, как и printf() и scanf(), за тем исключением, что работают с дисковыми файлами. Они имеют следующие прототипы:
int fprintf(FILE *fp, const char *форматная_строка,…);
int fscanf(FILE *fp, const char *форматная_строка,…);
где fp – это указатель на файл, возвращённый fopen().
Например, для чтения из файла длинных целых чисел в десятичной записи, разделенных пробелами и знаками перехода на новую строку, можно пользоваться следующим кодом:
#include <stdio.h>
int main()
{
long x;
int flag = 0;
FILE *fp;
if(NULL == (fp = fopen("test_in.txt","r"))){
puts("Cannot open file!");
return 1;
}
while(!feof(fp)){
flag = fscanf(fp, "%ld", &x);
if(flag == 1) printf("Input = %ld\n", x);
else if(flag == EOF) break;
else if(ferror(fp)){
puts("File error!");
return 1;
}
else {
puts("Format error!");
return 1;
}
}
fclose(fp);
return 0;
}
Функция rewind( )
Функция rewind() сбрасывает маркер файла на начало для файла, указанного в аргументе. Её прототип:
void rewind(FILE *fp);
где fp – допустимый файловый указатель.
Функция remove() удаляет файлы. Её прототип:
int remove(const char *имя_файла);
В случае удачного выполнения она возвращает 0, а в случае неудачного не 0.