Урок 10.5. Ввод-вывод форматный. Файл последовательного доступа
10.5. Ввод-вывод форматный. Файл последовательного доступа
При работе с файлами для форматного ввода и вывода данных предназначены функции fscanf() и fprintf() соответственно. Обращения к этим функциям задаются следующим образом:
fscanf(<указатель_файла>,<управляющая_строка>,<список_ввода>); fprintf(<указатель_файла>,<строка_вывода>,<список_вывода>); |
Легко заметить, что функции fscanf() и fprintf() аналогичны известным уже функциям scanf() и printf(), c той лишь разницей, что первым аргументом является указатель файла, из которого будут читаться или в который будут записываться данные. Таким образом, эти функции являются полными аналогами рассмотренных ранее функций форматного ввода-вывода, но работают не со стандартным системным вводом-выводом, а с конкретными текстовыми файлами. Ниже приведен пример печати (добавления) в существующий файл work.dta значения целой переменной cost:
FILE *fp; int cost=12; fp=fopen("work.dta","a"); fprintf(fp,"%5d",cost); fclose(fp); |
В конец файла будет добавлено 5 байтов точно так же, как это было бы выведено на экран или на принтер. Пример чтения данного из файла work.dta в переменную cost может быть следующим:
FILE *fp; int cost; fp=fopen("work.dta","r"); //или так, для VisualC++: //fopen_s(&fp, "work.dta", "r"); fscanf(fp,"%d",&cost); fscanf_s(fp, "%d",&cost); //для VisualC++: fclose(fp); |
В результате выполнения этого фрагмента программы самое первое целое число, записанное в файле work.dta в таком же виде, как оно бы вводилось с клавиатуры, станет значением переменной cost.
Рассмотрим более полный пример. В этом примере данные читаются с клавиатуры и записываются в файл последовательного доступа. В функции scanf_s() макрос _countof(fam) используется для подсчета количества символов в строке(массиве) с целью безопасного ввода. В этой программе с клавиатуры вводится номер студента, его фамилия и оценка, затем это все записывается в файл.
//Запись данных в файл последовательного доступа #include <stdio.h> #include <conio.h> #include <locale.h> #include <stdlib.h> //для _countof(fam) – макроса, вычисляющего //количество символов в статическом массиве. int main(void) { int n = 0; //номер char fam[15]; //фамилия int grade = 0; //оценка FILE *f; //FileStreamInput Output char *s = "Note.txt"; setlocale(LC_ALL,"Russian"); //открываем/создаем файл для записи errno_t err; err = fopen_s(&f, s, "wt"); if (err != 0) printf("Файл не открыт\n"); else { printf("Файл открыт\n" ); printf("Вводите номер, фамилию, оценку\n" "или введите конец файла(Ctrl-z)\n" "для окончания ввода\n"); printf(">"); scanf_s("%d%s%d", &n, fam, _countof(fam), &grade); while(!feof(stdin)) { //заполняем файл данными fprintf(f, "%d %s %d\n", n, fam, grade); printf(">"); scanf_s("%d%s%d", &n, fam, _countof(fam), &grade); } fclose(f); }//конец else puts("Завершение программы"); _getch(); return 0; } |
В следующем примере из файла, созданного в предыдущем примере (Note.txt) считываются данные и на экран выводятся только студенты с оценкой 0.
//чтение и вывод на экран //файла последовательного доступа #include <stdio.h> #include <conio.h> #include <locale.h> #include <stdlib.h> int main(void) { int n; //номер char fam[15]; //фамилия int grade = 0; //оценка FILE *f; //FileStreamInputOutput //char *s = "Note.txt"; setlocale(LC_ALL,"Russian"); //открываем/создаем файл для записи errno_t err; err = fopen_s(&f, "Note.txt", "r"); if (err != 0) printf("Файл не открыт\n"); else { printf("Файл открыт\n" ); printf("Номер Фамилия Оценка\n"); fscanf_s(f, "%d%s%d", &n, fam, _countof(fam), &grade); while(!feof(f)) { printf("%2d%-15s%2d\n",n, fam, grade); fscanf_s(f, "%d%s%d", &n, fam, _countof(fam), &grade); } rewind(f); printf( "\nСтуденты без оценки\n" ); printf("Номер Фамилия Оценка\n"); fscanf_s(f, "%d%s%d", &n, fam,_countof(fam), &grade); while(!feof(f)) { if(grade == 0) printf("%2d%-15s%2d\n",n, fam, grade); fscanf_s(f, "%d%s%d", &n, fam, _countof(fam), &grade); } fclose(f); } puts("Завершение программы"); _getch(); return 0; } |
При необходимости обработать данные из файла последовательного доступа несколько раз в ходе выполнения программы (каждый раз начиная с первой записи), можно использовать функцию rewind(). Использование этой функции позволяет переместить указатель на текущую позицию файла из любого его положения к началу файла. Обращение к функции имеет вид:
rewind(<указатель_файла>); |
Оставить комментарий