Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Функция fprintf






#include < stdio.h> int fprintf(FILE * stream, const char * format,...);

Функция fprintf() выводит в поток, адресуемый параметром stream, значения аргументов, составляющих список аргументов, в соответствии с заданной строкой формата format. Возвращаемое значение равно количеству реально выведенных символов. Если при выводе возникла ошибка, возвращается отрицательное число.

#include < stdio.h> int fscanf(FILE * stream, const char * format,...);

Функция fscanf() работает подобно функции scanf(), но читает информацию не из стандартного потока ввода stdin, а из потока, заданного указателем stream. Подробности рассматриваются в разделе этой главы, посвященном функции scanf.

Функция fscanf() возвращает количество аргументов, которым действительно присвоены значения. Это число не включает опущенные поля. Если возвращаемое функцией значение равно EOF, то это свидетельствует о том, что до выполнения первого присваивания произошел сбой.

#include < stdio.h>

main()

{

FILE *fi;

int age;

fi=fopen(" File", " r"); /* считывание */

fscanf(fi, " %d", & age); /* fi указывает на File */

fclose(fi);

fi=fopen(" Data", " a"); /*дополнение*/

fprintf(fi, " Data is %d.\n", age);

/*fi указывает на Data*/

fclose(fi);

}

Функция fgets()

include < stdio.h> char *fgets(char * str, int num, FILE * stream);

Функция fgets() читает из входного потока stream не более num-1 символов и помещает их в массив символов, адресуемый указателем str. Символы читаются до тех пор, пока не будет прочитан символ новой строки или значение EOF, либо пока не будет достигнут заданный предел. По завершении чтения символов сразу же за последним из них размещается нулевой символ. Символ новой строки сохраняется и становится частью массива, адресуемого элементом str.

/* Программа считывает файл строка за строкой */

#include < stdio.h>

#define MAX 80

main()

{

FILE *f1;

char *string[MAX];

f1=fopen(" File", " r");

while (fgets(string, MAX, f1)! = NULL)

puts(string);

}

Мы расположили вводимую информацию в символьном массиве string. Первый из трех аргументов функции fgets() является указателем на местоположение считываемой строки. Второй аргумент содержит предельную длину считываемой строки. Функция прекращает работу после считывания символа новой строки или после считывания символов общим числом MAX-1, в зависимости от того, что произойдет раньше. В любом случае нуль-символ '\0' добавляется в самый конец строки. Третий аргумент указывает на файл, который будет читаться.

Разница между gets() и fgets() заключается в том, что gets() заменяет символ новой строки на '\0', в то время как fgets() сохраняет символ новой строки. Подобно gets() функция fgets() возвращает значение NULL, если встречает символ EOF. Это позволяет нам проверить, достигли ли мы конца файла.

Функция fputs()

#include < stdio.h> int fputs(const char * str, FILE * stream);

Функция fputs() записывает в заданный поток stream содержимое строки, адресуемой указателем str. При этом завершающий нулевой символ (т.е. символ конца строки ('0')) не записывается.

В версии C99 к параметрам str и stream применен квалификатор restrict.

При успешном выполнении функция fputs() возвращает неотрицательное значение, а при неудачном — значение EOF.

Если поток открыт в текстовом режиме, могут произойти преобразования некоторых символов. Это значит, что однозначного отображения строки в файл может и не быть. Однако если поток открыт в двоичном режиме, никаких преобразований символов не будет и строка отобразится в файл " один к одному".

l=fputs(" Строка", fi);

   
   
   
   

Передает строку " Строка" в файл, на который ссылается указатель fi типа FILE. Конечно, сначала нужно открыть файл при помощи функции fopen().

 


Поток по умолчанию буферизован, поэтому закрытие файла освобождает буфер. Однако имеется возможность явно указать освобождение буфера в любой момент работы программы, не закрывая файл. Для этого используется функция

int fflush(FILE *имя);


Аналогично функции закрытия файла в случае успешной записи буфера в файл возвращается ноль, иначе — EOF.
Важнейшей функцией является функция, проверяющая, достигнут ли конец файла. Ее прототип

int feof(FILE *имя);


Очевидно, конец файла может обнаружиться только при чтении из файла. Если в результате очередной операции ввода достигнут конец файла, система устанавливает внутренний индикатор конца файла. Этот индикатор и проверяет данная функция. Если достигнут конец файла, то функция возвращает ненулевое значение, иначе возвращается 0.


Двоичные файлы
Двоичные и текстовые файлы — это, как говорят в Одессе, «две большие разницы». Обмен данными между программой и двоичным потоком выполняется без всякого преобразования, поэтому работает быстрее. Двоичный ввод выполняется функцией fread(), имеющей следующий прототип:

size_t fread(void *buffer, size_t size, size_t n, FILE *stream);


Тип size_t обычно определен как unsigned int. Первый параметр часто определяет массив (или указатель на динамический массив), в который будет прочитана информация; третий параметр задает размер одного элемента данных в байтах, а второй — количество читаемых элементов. Четвертый параметр определяет двоичный файл, из которого информация вводится. Общее количество считанных байтов равно size*n. Однако возвращает функция количество корректно прочитанных элементов, а не байтов.
Вывод в двоичный файл выполняется функцией fwrite(), которая имеет совершенно аналогичный прототип:

size_t fwrite(const void *buffer, size_t size, size_t n, FILE *stream);


Функция записывает n элементов размера size в двоичный файл stream из буфера, указатель на который задается в качестве первого аргумента. Общее количество выводимых байтов равно size*n. Однако возвращает функция количество корректно записанных элементов, а не байтов.
В качестве элементов могут использоваться любые переменные любых типов, в том числе и динамические. Даже массив может быть одним-единственным элементом! Рассмотрим несколько простых примеров, аналогичных примерам для текстовых файлов (см. листинги 10.8, 10.9). Создадим на диске C: каталог BinFiles и все двоичные файлы будем размещать в нем. Переделаем пример создания файла (листинг 10.12).

//Листинг 10.12. Создание и чтение двоичных файлов #include < cstdio> #include < cstdlib> #include < ctime> int main() { int m[10]={0}; srand((unsigned)time(NULL)); // инициализация датчика случайных чисел FILE *stream; /* открываем двоичный файл для записи */ if((stream = fopen(" c: /binfiles/number1.bin", " wb")) == NULL) return 1; // ошибка при открытии /* заполняем массив m числами */ for(int i = 0; i < 10; i++) m[i] = rand()%10; // случайные числа от 0 до 9 // заполняем файл number1.bin элементами-числами for(int i = 0; i < 10; i++) fwrite(& m[i], 1, sizeof(int), stream); fclose(stream); // закрываем файл /* открываем другой файл для записи */ if((stream = fopen(" c: /binfiles/number2.bin", " wb")) == NULL) return 1; // ошибка при открытии // заполняем файл number2.bin элементом-массивом fwrite(m, 1, sizeof(m), stream); // массив - один элемент fclose(stream); // закрываем файл // вывод второго двоичного файла на экран // открываем файл для чтения if((stream = fopen(" c: /binfiles/number2.bin", " rb")) == NULL) return 1; // ошибка при открытии int a = 0; // сюда вводим // читаем второй файл поэлементно // правильный цикл fread(& a, 1, sizeof(int), stream); // предварительное чтение while(! feof(stream)) // пока не конец файла { printf(" %d\n", a); fread(& a, 1, sizeof(int), stream); } fclose(stream); // открываем первый файл в режиме чтения if((stream = fopen(" c: /binfiles/number1.bin", " rb")) == NULL) return 1; int t[10] = {0}; // массив для чтения // читаем первый файл как массив fread(t, 1, sizeof(t), stream); for(int i = 0; i < 10; i++) // выводим поэлементно printf(" %d\n", t[i]); fclose(stream); char ch = getchar(); return 0; }


В этой программе сначала создается два двоичных файла: number1.bin и number2.bin. В первый файл целые числа из массива m записываются по одному в цикле. Во второй файл весь массив записывается сразу как один элемент. Затем файлы открываются для чтения. Сначала открывается файл number2.bin (в который мы писали массив целиком), и чтение из него выполняется по одному числу. Проверка конца файла делается так же, как и для текстовых файлов. На экране видно, что чтение выполняется совершенно правильно.
Первый файл number1.bin, который записывался в цикле по одному числу, читается сразу целиком в массив t, а вывод осуществляется по одному числу. И снова мы наблюдаем на экране, что чтение выполнилось совершенно правильно. Такое «смешивание» для двоичных файлов безопасно, так как и в памяти, и на диске размеры данных равны sizeof(тип)*n, где n — количество элементов, участвующих в обмене.
Теперь добавим в конец этого примера строки, выполняющие суммирование чисел, записанных в файл number1.bin.

// суммирование чисел записанных в файле if((stream = fopen(" c: /binfiles/number1.bin", " rb")) == NULL) return 1; // ошибка при открытии // читаем числа по одному из файла и считаем int number, summa = 0, count = 0; fread(& number, 1, sizeof(int), stream); while(! feof(stream)) { printf(" %d\n", number); ++count; summa+=number; fread(& number, 1, sizeof(int), stream); } printf(" %d %d\n", summa, count); fclose(stream);


Как видим, этот текст отличается от приведенного выше для текстовых файлов только режимом открытия и функцией ввода данных.
Так как функции посимвольного ввода/вывода fgetc() и fputc() фактически не выполняют никакого преобразования информации, то копирование двоичных файлов можно делать точно так же, как и текстовых — посимвольно. Используем функцию filecopy(), представленную в листинге 10.9.

// копирование файлов FILE *in, *out; if((in = fopen(" c: /binfiles/number1.bin", " rb")) == NULL) { printf (" Error input file! "); return 1; // ошибка при открытии } if((out = fopen(" c: /binfiles/number1.new", " wb")) == NULL) { printf (" Error output file! "); return 1; // ошибка при открытии } filecopy(in, out); // копирование fclose(in); fclose(out);


Соответственно и для объединения файлов можно использовать ту же функцию — все определяется режимом открытия файла.

// дозапись нового файла в конец старого if((out = fopen(" c: /binfiles/number1.bin", " ab")) == NULL) { printf (" Error output file! "); return 1; } if((in = fopen(" c: /binfiles/number1.new", " rb")) == NULL) { printf (" Error input file! "); return 1; } filecopy(in, out); // объединение – дозапись! fclose(in); fclose(out);


Для проверки правильности объединения выведем содержимое файла на экран. Используем вторую форму проверки окончания файла — внутри цикла:

// вывод нового файла на экран для проверки if((stream = fopen(" c: /binfiles/number1.bin", " rb")) == NULL) return 1; while(true) { fread(& a, 1, sizeof(int), stream); if (feof(stream)) break; printf(" %d\n", a); } fclose(stream);

Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.007 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал