На этом шаге мы приведем решения нескольких задач с использованием файлов.
#include <iostream.h> #include <stdio.h> void main (int argc,char *argv[]) { FILE *in; /* ------ */ if (argc < 2) cout << "Отсутствует имя файла в командной строке."; else { in = fopen (argv[1],"w"); fclose (in); } }
#include <iostream.h> #include <stdio.h> #include <string.h> void main (int argc,char *argv[]) { FILE *in,*out; char ch; static char name[20]; int count=0; /* -------------------- */ if (argc < 2) /* Проверяем, введено ли имя входного файла. */ cout << "Отсутствует имя файла \n"; else { if ((in=fopen(argv[1],"r")) != NULL) { /* Копируем имя файла в строку. */ strcpy (name,argv[1]); /* Проверяем, есть ли расширение. */ char *p = strchr (name,'.'); if (p) *p=NULL; //Удалить расширение. /* Добавляем .red к имени файла. */ out = fopen (strcat (name,".red"),"w"); while ( (ch=getc (in)) != EOF) /* Печатаем каждый третий символ файла. */ if (count++%3==0) putc (ch,out); fclose (in); fclose (out); } else cout << "Файл не существует!"; } }
Теперь если мы поместим эту программу в файл c70_2.cpp и откомпилируем ее, а в файл edd.txt поместим Даже Эдди нас опередил с детским хором, то после выполнения командной строки:
C:\>c70_2.exe edd.txt
#include <iostream.h> #include <stdio.h> void main (int argc,char *argv[]) { FILE *in; char t; /* ------ */ if (argc < 2) cout << "Не заданы параметры в командной строке \n"; else for (int i=1; i < argc; i++) if ((in=fopen(argv[i],"r")) != NULL) { cout << "Содержимое файла \"" << argv[i] << "\":" << endl; while ((t=getc(in)) != EOF) cout << t; fclose (in); cout << endl; } else cout << "Файла с именем \"" << argv[i] << "\" нет"; }
#include <iostream.h> #include <stdio.h> void main (int argc,char *argv[]) { FILE *in,*out; char a; /* -------- */ if (argc < 3) cout << "Не заданы параметры в командной строке \n"; else { in = fopen (argv[1],"r"); out = fopen (argv[2],"w"); int i = -1; while (!fseek(in,i,SEEK_END)) { a=getc(in); if ((int)a==0x0a) {putc('\n',out); i--; } else putc (a,out); i--; } fclose (in); fclose (out); } }
Прокомментируем текст приведенной программы. Сначала немного поясним общий ход решения задачи. Будем читать посимвольно содержимое первого файла (с конца файла!) и записывать в начало второго файла. Для того, чтобы осуществить чтение с конца файла, нужно разместить там файловый указатель. Это осуществляется функцией
fseek(in,i,SEEK_END)
Будем выполнять эту функцию, пока возможно (то есть пока она не вернет нулевое значение). Параметр SEEK_END говорит о том, что отсчет будет идти от конца файла. В этом случае количество байтов, которое нужно отсчитать должно быть отрицательным, поэтому переменная i последовательно принимает значения: -1, -2 и т.д.
Поясним условие
if ((int)a==0x0a) {putc('\n',out); i--; }
Переход на следующую строку в файле кодируется двумя байтами: 0D 0A. Так как мы читаем
содержимое первого файла с конца, то первый прочитанный байт будет 0A. Если
мы его встретили, то во второй файл помещаем символ перехода на новую строку ('\n') и
пропускаем следующий байт (0D) командой i--, переходя к очередному байту.
На следующем шаге мы поговорим о форматном вводе/выводе.