#include <stdio.h>
int main()
{
FILE *fp;
char ch;
fp = fopen(__FILE__,"r");
while (ch != EOF)
{
ch = getc(fp);
putchar(ch);
}
fclose(fp);
return 0;
}
- 177
1 Answers
FILE *fp;
Объявляем указатель на файл. FILE - действительно тип данных (структура), этот указатель может указывать на неё. Именно на неё, а не на какое-то "начало файла". Но пока ему не присвоили значение, там лежит просто мусор.
fp = fopen(__FILE__,"r");
Открываем файл исходника для чтения в тектовом режиме. Вместо __FILE__ препроцессор подставляет с код строку с именем текущего файла. Соответственно, чтобы программа работала, файл с её исходным кодом должен лежать рядом с ней (точнее в её рабочем каталоге, но в большинстве случаев они будут совпадать).
Обычно это не так.
while (ch != EOF)
Пока считанный символ не будет концом файла. Сразу 3 ошибки, связанные с этой строчкой. Во-первых, изначально переменная ch ничем не инициализировалась, чтение неинициализированной переменной - это уже UB. Во-вторых, переменная объявлена с типом char, а весь диапазон типа char является корректными символами, которые могут встретиться в самом файле. В данном случае для файла в кодировке win1251 концом файла посчитается буква я, если она вдруг там окажется. EOF - специальная константа типа int (обычно -1), обозначающая, что читать уже нечего и файл закончился. Это вообще не указатель, и тем более не указатель на конец файла. Ну а третья ошибка в том, что проверка происходит уже после того, как произойдёт вывод на экран, так что привет буква я в конце файла.
ch = getc(fp); putchar(ch);
Собственно считываем очередной символ и выводим. Как я уже сказал, выводим лишнее.
fclose(fp);
И закрываем за собой файл когда всё готово.
Есть, кстати, даже соревнование, заключающееся в том, чтобы написать минимальную программу, которая выводит саму себя на экран.
Программа, выводящая саму себя называется квайном, но почти всегда там запрещается чтение исходника. И уж тем более чтение исходника из файла, который должен просто так лежать рядом.
- 123,725
__FILE__. Подбробнее о этих макросах можете найти в темах про "директивы препроцессора в Си/С++". – Alex Krass Mar 06 '19 at 09:15chи о сохранении результатаgetc()в переменную типаchar. – AnT stands with Russia Mar 06 '19 at 09:56undefined behaviour. – Alex Krass Mar 06 '19 at 12:03я. И нигде не объявленное требование на то, чтобы исходник лежал рядом. Комментарии снести в чат можно, но смысла не вижу, тем более, этот вопрос через полгода удалится. – Qwertiy Mar 06 '19 at 17:16