Функция заполнения строки из файла с. Работа с файлами в языке си

Существуют два основных типа файлов: текстовые и двоичные. Файлы позволяют пользователю считывать большие объемы данных непосредственно с диска, не вводя их с клавиатуры.

    Текстовыми называются файлы, состоящие из любых символов. Они организуются по строкам, каждая из которых заканчивается символом «конец строки». Конец самого файла обозначается символом «конец файла». При записи информации в текстовый файл, просмотреть который можно с помощью любого текстового редактора, все данные преобразуются к символьному типу и хранятся в символьном виде.

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

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

В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream.

Для того чтобы записывать данные в текстовый файл, необходимо:

    описать переменную типа ofstream.

    вывести информацию в файл.

    обязательно закрыть файл.

Для считывания данных из текстового файла, необходимо:

    описать переменную типа ifstream.

    открыть файл с помощью функции open.

    закрыть файл.

Запись информации в текстовый файл

    Как было сказано ранее, для того чтобы начать работать с текстовым файлом, необходимо описать переменную типа ofstream. Например, так:

    Будет создана переменная F для записи информации в файл.

    На следующим этапе файл необходимо открыть для записи. В общем случае оператор открытия потока будет иметь вид:

F.open(«file», mode);

Здесь F - переменная, описанная как ofstream,

file - полное имя файла на диске,

mode - режим работы с открываемым файлом.

Обратите внимание на то, что при указании полного имени файла нужно ставить двойной слеш. Например, полное имя файла noobs.txt, находящегося в папке game на диске D:, нужно будет записать так:

D:\\game\\noobs.txt.

Файл может быть открыт в одном из следующих режимов:

ios::in - открыть файл в режиме чтения данных, этот режим является режимом по умолчанию для потоков ifstream;

ios::out - открыть файл в режиме записи данных (при этом информация о существующем файле уничтожается), этот режим является режимом по умолчанию для потоков ofstream;

ios::app - открыть файл в режиме записи данных в конец файла;

ios::ate - передвинуться в конец уже открытого файла;

ios::trunc - очистить файл, это же происходит в режиме ios::out;

ios::nocreate - не выполнять операцию открытия файла, если он не существует;

ios::noreplace - не открывать существующий файл.

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

После удачного открытия файла (в любом режиме) в переменной F будет храниться true, в противном случае false. Это позволит проверить корректность операции открытия файла.

Открыть файл (в качестве примера возьмем файл D:\\game\\noobs.txt) в режиме записи можно одним из следующих способов:

// первый способ

ofstream F;

F.open("D:\\game\\noobs.txt", ios::out);

//второй способ, режим ios::out является режимом по умолчанию

// для потока ofstream

ofstream F;

//третий способ объединяет описание переменной и типа поток

//и открытие файла в одном операторе

ofstream F ("D:\\game\\noobs.txt", ios::out);

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

Если вы хотите открыть существующий файл в режиме до записи, то в качестве режима следует использовать значение ios::app.

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

Например, для записи в поток F переменной a, оператор вывода будет иметь вид:

Для последовательного вывода в поток G переменных b, c, d оператор вывода станет таким:

G<

Закрытие потока осуществляется с помощью оператора:

ПРИМЕР:

Создать текстовый файл D:\\game\\noobs.txt и записать в него n вещественных чисел.

#include "stdafx.h"

#include

#include

#include

using namespace std;

int main()

setlocale (LC_ALL, "RUS");

int i, n;

double a;

//описывает поток для записи данных в файл

ofstream f ;

//открываем файл в режиме записи,

//режим ios :: out устанавливается по умолчанию

f.open("D:\\game\\noobs.txt", ios::out);

//вводим количество вещественных чисел

cout <<" n ="; cin >> n ;

//цикл для ввода вещественных чисел

//и записи их в файл

for (i=0; i

cout<<"a=";

//ввод числа

cin>>a;

f<

//закрытие потока

f.close();

system("pause");

return 0;

_______________________________________________________________

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

F.open("D:\\game\\noobs.txt", ios::in);

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

Например, для чтения из потока F в переменную a, оператор ввода будет выглядеть так:

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

Здесь F - имя потока функция возвращает логическое значение: true или false, в зависимости от того достигнут ли конец файла. Следовательно, цикл для чтения содержимого всего файла можно записать так:

//организуем для чтения значений из файла, выполнение

//цикла прервется, когда достигнем конец файла,

//в этом случае F.eof() вернет истину

while (!F.eof())

ПРИМЕР:

В текстовом файле D:\\game\\noobs.txt хранятся вещественные числа, вывести их на экран и вычислить их количество.

#include "stdafx.h"

#include

#include

#include

#include

using namespace std;

int main()

setlocale (LC_ALL, "RUS");

int n=0;

float a;

fstream F;

//открываем файл в режиме чтения

F.open("D:\\game\\noobs.txt");

//если открытие файла прошло корректно, то

//цикл для чтения значений из файла; выполнение цикла прервется,

//когда достигнем конца файла, в этом случае F.eof() вернет истину.

while (!F.eof())

//чтение очередного значения из потока F в переменную a

F>>a;

//вывод значения переменной a на экран

cout<

//увеличение количества считанных чисел

//закрытие потока

F.close();

//вовод на экран количества считанных чисел

cout<<"n="<

//если открытие файла прошло некорректно, то вывод

//сообщения об отсутствии такого файла

else cout<<" Файл не существует"<

system("pause");

Теги: Текстовые файлы, fopen, fclose, feof, setbuf, setvbuf, fflush, fgetc, fprintf, fscanf, fgets, буферизированный поток, небуферизированный поток.

Работа с текстовыми файлами

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

  • 1. Открыть файл, для того, чтобы к нему можно было обращаться. Соответственно, открывать можно для чтения, записи, чтения и записи, переписывания или записи в конец файла и т.п. Когда вы открываете файл, может также произойти куча ошибок – файла может не существовать, это может быть файл не того типа, у вас может не быть прав на работу с файлом и т.д. Всё это необходимо учитывать.
  • 2. Непосредственно работа с файлом - запись и чтение. Здесь также нужно помнить, что мы работаем не с памятью с произвольным доступом, а с буферизированным потоком, что добавляет свою специфику.
  • 3. Закрыть файл. Так как файл является внешним по отношению к программе ресурсом, то если его не закрыть, то он продолжит висеть в памяти, возможно, даже после закрытия программы (например, нельзя будет удалить открытый файл или внести изменения и т.п.). Кроме того, иногда необходимо не закрывать, а "переоткрывать" файл для того, чтобы, например, изменить режим доступа.

Кроме того, существует ряд задач, когда нам не нужно обращаться к содержимому файла: переименование, перемещение, копирование и т.д. К сожалению, в стандарте си нет описания функций для этих нужд. Они, безусловно, имеются для каждой из реализаций компилятора. Считывание содержимого каталога (папки, директории) – это тоже обращение к файлу, потому что папка сама по себе является файлом с метаинформацией.

Иногда необходимо выполнять некоторые вспомогательные операции: переместиться в нужное место файла, запомнить текущее положение, определить длину файла и т.д.

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

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

Создание и выделение памяти под объект типа FILE осуществляется с помощью функции fopen или tmpfile (есть и другие, но мы остановимся только на этих).

Функция fopen открывает файл. Она получает два аргумента – строку с адресом файла и строку с режимом доступа к файлу. Имя файла может быть как абсолютным, так и относительным. fopen возвращает указатель на объект FILE, с помощью которого далее можно осуществлять доступ к файлу.

FILE* fopen(const char* filename, const char* mode);

Например, откроем файл и запишем в него Hello World

#include #include #include void main() { //С помощью переменной file будем осуществлять доступ к файлу FILE *file; //Открываем текстовый файл с правами на запись file = fopen("C:/c/test.txt", "w+t"); //Пишем в файл fprintf(file, "Hello, World!"); //Закрываем файл fclose(file); getch(); }

Функция fopen сама выделяет память под объект, очистка проводится функцией fclose. Закрывать файл обязательно, самостоятельно он не закроется.

Функция fopen может открывать файл в текстовом или бинарном режиме. По умолчанию используется текстовый. Режим доступа может быть следующим

Параметры доступа к файлу.
Тип Описание
r Чтение. Файл должен существовать.
w Запись нового файла. Если файл с таким именем уже существует, то его содержимое будет потеряно.
a Запись в конец файла. Операции позиционирования (fseek, fsetpos, frewind) игнорируются. Файл создаётся, если не существовал.
r+ Чтение и обновление. Можно как читать, так и писать. Файл должен существовать.
w+ Запись и обновление. Создаётся новый файл. Если файл с таким именем уже существует, то его содержимое будет потеряно. Можно как писать, так и читать.
a+ Запись в конец и обновление. Операции позиционирования работают только для чтения, для записи игнорируются. Если файл не существовал, то будет создан новый.

Если необходимо открыть файл в бинарном режиме, то в конец строки добавляется буква b, например “rb”, “wb”, “ab”, или, для смешанного режима “ab+”, “wb+”, “ab+”. Вместо b можно добавлять букву t, тогда файл будет открываться в текстовом режиме. Это зависит от реализации. В новом стандарте си (2011) буква x означает, что функция fopen должна завершиться с ошибкой, если файл уже существует. Дополним нашу старую программу: заново откроем файл и считаем, что мы туда записали.

#include #include #include void main() { FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); fprintf(file, "Hello, World!"); fclose(file); file = fopen("C:/c/test.txt", "r"); fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch(); }

Вместо функции fgets можно было использовать fscanf, но нужно помнить, что она может считать строку только до первого пробела.
fscanf(file, "%127s", buffer);

Также, вместо того, чтобы открывать и закрывать файл можно воспользоваться функцией freopen, которая «переоткрывает» файл с новыми правами доступа.

#include #include #include void main() { FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); fprintf(file, "Hello, World!"); freopen("C:/c/test.txt", "r", file); fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch(); }

Функции fprintf и fscanf отличаются от printf и scanf только тем, что принимают в качестве первого аргумента указатель на FILE, в который они будут выводить или из которого они будут читать данные. Здесь стоит сразу же добавить, что функции printf и scanf могут быть без проблем заменены функциями fprintf и fscanf. В ОС (мы рассматриваем самые распространённые и адекватные операционные системы) существует три стандартных потока: стандартный поток вывода stdout, стандартный поток ввода stdin и стандартный поток вывода ошибок stderr. Они автоматически открываются во время запуска приложения и связаны с консолью. Пример

#include #include #include void main() { int a, b; fprintf(stdout, "Enter two numbers\n"); fscanf(stdin, "%d", &a); fscanf(stdin, "%d", &b); if (b == 0) { fprintf(stderr, "Error: divide by zero"); } else { fprintf(stdout, "%.3f", (float) a / (float) b); } getch(); }

Ошибка открытия файла

Если вызов функции fopen прошёл неудачно, то она возвратит NULL. Ошибки во время работы с файлами встречаются достаточно часто, поэтому каждый раз, когда мы окрываем файл, необходимо проверять результат работы

#include #include #include #define ERROR_OPEN_FILE -3 void main() { FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); if (file == NULL) { printf("Error opening file"); getch(); exit(ERROR_OPEN_FILE); } fprintf(file, "Hello, World!"); freopen("C:/c/test.txt", "r", file); if (file == NULL) { printf("Error opening file"); getch(); exit(ERROR_OPEN_FILE); } fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch(); }

Проблему вызывает случай, когда открывается сразу несколько файлов: если один из них нельзя открыть, то остальные также должны быть закрыты

FILE *inputFile, *outputFile; unsigned m, n; unsigned i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); if (inputFile == NULL) { printf("Error opening file %s", INPUT_FILE); getch(); exit(3); } outputFile = fopen(OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) { printf("Error opening file %s", OUTPUT_FILE); getch(); if (inputFile != NULL) { fclose(inputFile); } exit(4); } ...

В простых случаях можно действовать влоб, как в предыдущем куске кода. В более сложных случаях используются методы, подменяющиее RAII из С++: обёртки, или особенности компилятора (cleanup в GCC) и т.п.

Буферизация данных

Как уже говорилось ранее, когда мы выводим данные, они сначала помещаются в буфер. Очистка буфера осуществляется

  • 1) Если он заполнен
  • 2) Если поток закрывается
  • 3) Если мы явно указываем, что необходимо очистить буфер (здесь тоже есть исключения:)).
  • 4) Также очищается, если программа завершилась удачно. Вместе с этим закрываются и все файлы. В случае ошибки выполнения этого может не произойти.

Форсировать выгрузку буфера можно с помощью вызова функции fflush(File *). Рассмотрим два примера – с очисткой и без.

#include #include #include void main() { FILE *file; char c; file = fopen("C:/c/test.txt", "w"); do { c = getch(); fprintf(file, "%c", c); fprintf(stdout, "%c", c); //fflush(file); } while(c != "q"); fclose(file); getch(); }

Раскомментируйте вызов fflush. Во время выполнения откройте текстовый файл и посмотрите на поведение.

Буфер файла можно назначить самостоятельно, задав свой размер. Делается это при помощи функции

Void setbuf (FILE * stream, char * buffer);

которая принимает уже открытый FILE и указатель на новый буфер. Размер нового буфера должен быть не меньше чем BUFSIZ (к примеру, на текущей рабочей станции BUFSIZ равен 512 байт). Если передать в качестве буфера NULL, то поток станет небуферизированным. Можно также воспользоваться функцией

Int setvbuf (FILE * stream, char * buffer, int mode, size_t size);

которая принимает буфер произвольного размера size. Режим mode может принимать следующие значения

  • _IOFBF - полная буферизация. Данные записываются в файл, когда он заполняется. На считывание, буфер считается заполненным, когда запрашивается операция ввода и буфер пуст.
  • _IOLBF - линейная буферизация. Данные записываются в файл когда он заполняется, либо когда встречается символ новой строки. На считывание, буфер заполняется до символа новой строки, когда запрашивается операция ввода и буфер пуст.
  • _IONBF – без буферизации. В этом случае параметры size и buffer игнорируются.
В случае удачного выполнения функция возвращает 0.

Пример: зададим свой буфер и посмотрим, как осуществляется чтение из файла. Пусть файл короткий (что-нибудь, типа Hello, World!), и считываем мы его посимвольно

#include #include #include void main() { FILE *input = NULL; char c; char buffer = {0}; input = fopen("D:/c/text.txt", "rt"); setbuf(input, buffer); while (!feof(input)) { c = fgetc(input); printf("%c\n", c); printf("%s\n", buffer); _getch(); } fclose(input); }

Видно, что данные уже находятся в буфере. Считывание посимвольно производится уже из буфера.

feof

Функция int feof (FILE * stream); возвращает истину, если конец файла достигнут. Функцию удобно использовать, когда необходимо пройти весь файл от начала до конца. Пусть есть файл с текстовым содержимым text.txt. Считаем посимвольно файл и выведем на экран.

#include #include #include void main() { FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) { printf("Error opening file"); _getch(); exit(0); } while (!feof(input)) { c = fgetc(input); fprintf(stdout, "%c", c); } fclose(input); _getch(); }

Всё бы ничего, только функция feof работает неправильно... Это связано с тем, что понятие "конец файла" не определено. При использовании feof часто возникает ошибка, когда последние считанные данные выводятся два раза. Это связано с тем, что данные записывается в буфер ввода, последнее считывание происходит с ошибкой и функция возвращает старое считанное значение.

#include #include #include void main() { FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) { printf("Error opening file"); _getch(); exit(0); } while (!feof(input)) { fscanf(input, "%c", &c); fprintf(stdout, "%c", c); } fclose(input); _getch(); }

Этот пример сработает с ошибкой (скорее всего) и выведет последний символ файла два раза.

Решение – не использовать feof. Например, хранить общее количество записей или использовать тот факт, что функции fscanf и пр. обычно возвращают число верно считанных и сопоставленных значений.

#include #include #include void main() { FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) { printf("Error opening file"); _getch(); exit(0); } while (fscanf(input, "%c", &c) == 1) { fprintf(stdout, "%c", c); } fclose(input); _getch(); }

Примеры

1. В одном файле записаны два числа - размерности массива. Заполним второй файл массивом случайных чисел.

#include #include #include #include //Имена файлов и права доступа #define INPUT_FILE "D:/c/input.txt" #define OUTPUT_FILE "D:/c/output.txt" #define READ_ONLY "r" #define WRITE_ONLY "w" //Максимальное значение для размера массива #define MAX_DIMENSION 100 //Ошибка при открытии файла #define ERROR_OPEN_FILE -3 void main() { FILE *inputFile, *outputFile; unsigned m, n; unsigned i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); if (inputFile == NULL) { printf("Error opening file %s", INPUT_FILE); getch(); exit(ERROR_OPEN_FILE); } outputFile = fopen(OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) { printf("Error opening file %s", OUTPUT_FILE); getch(); //Если файл для чтения удалось открыть, то его необходимо закрыть if (inputFile != NULL) { fclose(inputFile); } exit(ERROR_OPEN_FILE); } fscanf(inputFile, "%ud %ud", &m, &n); if (m > MAX_DIMENSION) { m = MAX_DIMENSION; } if (n > MAX_DIMENSION) { n = MAX_DIMENSION; } srand(time(NULL)); for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { fprintf(outputFile, "%8d ", rand()); } fprintf(outputFile, "\n"); } //Закрываем файлы fclose(inputFile); fclose(outputFile); }

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

#include #include #include #define ERROR_FILE_OPEN -3 void main() { FILE *origin = NULL; FILE *output = NULL; char filename; int mode; printf("Enter filename: "); scanf("%1023s", filename); origin = fopen(filename, "r"); if (origin == NULL) { printf("Error opening file %s", filename); getch(); exit(ERROR_FILE_OPEN); } printf("enter mode: "); scanf("%d", &mode); if (mode == 1) { printf("Enter filename: "); scanf("%1023s", filename); output = fopen(filename, "w"); if (output == NULL) { printf("Error opening file %s", filename); getch(); fclose(origin); exit(ERROR_FILE_OPEN); } } else { output = stdout; } while (!feof(origin)) { fprintf(output, "%c", fgetc(origin)); } fclose(origin); fclose(output); getch(); }

3. Пользователь вводит данные с консоли и они записываются в файл до тех пор, пока не будет нажата клавиша esc. Проверьте программу и посмотрите. как она себя ведёт в случае, если вы вводите backspace: что выводится в файл и что выводится на консоль.

#include #include #include #define ERROR_FILE_OPEN -3 void main() { FILE *output = NULL; char c; output = fopen("D:/c/test_output.txt", "w+t"); if (output == NULL) { printf("Error opening file"); _getch(); exit(ERROR_FILE_OPEN); } for (;;) { c = _getch(); if (c == 27) { break; } fputc(c, output); fputc(c, stdout); } fclose(output); }

4. В файле записаны целые числа. Найти максимальное из них. Воспользуемся тем, что функция fscanf возвращает число верно прочитанных и сопоставленных объектов. Каждый раз должно возвращаться число 1.

#include #include #include #define ERROR_FILE_OPEN -3 void main() { FILE *input = NULL; int num, maxn, hasRead; input = fopen("D:/c/input.txt", "r"); if (input == NULL) { printf("Error opening file"); _getch(); exit(ERROR_FILE_OPEN); } maxn = INT_MIN; hasRead = 1; while (hasRead == 1) { hasRead = fscanf(input, "%d", &num); if (hasRead != 1) { continue; } if (num >

Другое решение считывать числа, пока не дойдём до конца файла.

#include #include #include #include #define ERROR_FILE_OPEN -3 void main() { FILE *input = NULL; int num, maxn, hasRead; input = fopen("D:/c/input.txt", "r"); if (input == NULL) { printf("Error opening file"); _getch(); exit(ERROR_FILE_OPEN); } maxn = INT_MIN; while (!feof(input)) { fscanf(input, "%d", &num); if (num > maxn) { maxn = num; } } printf("max number = %d", maxn); fclose(input); _getch(); }

5. В файле записаны слова: русское слово, табуляция, английское слово, в несколько рядов. Пользователь вводит английское слово, необходимо вывести русское.

Файл с переводом выглядит примерно так

Солнце sun
карандаш pen
шариковая ручка pencil
дверь door
окно windows
стул chair
кресло armchair

и сохранён в кодировке cp866 (OEM 866). При этом важно: последняя пара cлов также заканчивается переводом строки.

Алгоритм следующий - считываем строку из файла, находим в строке знак табуляции, подменяем знак табуляции нулём, копируем русское слово из буфера, копируем английское слово из буфера, проверяем на равенство.

#include #include #include #include #define ERROR_FILE_OPEN -3 void main() { FILE *input = NULL; char buffer; char enWord; char ruWord; char usrWord; unsigned index; int length; int wasFound; input = fopen("D:/c/input.txt", "r"); if (input == NULL) { printf("Error opening file"); _getch(); exit(ERROR_FILE_OPEN); } printf("enter word: "); fgets(usrWord, 127, stdin); wasFound = 0; while (!feof(input)) { fgets(buffer, 511, input); length = strlen(buffer); for (index = 0; index < length; index++) { if (buffer == "\t") { buffer = "\0"; break; } } strcpy(ruWord, buffer); strcpy(enWord, &buffer); if (!strcmp(enWord, usrWord)) { wasFound = 1; break; } } if (wasFound) { printf("%s", ruWord); } else { printf("Word not found"); } fclose(input); _getch(); }

6. Подсчитать количество строк в файле. Будем считывать файл посимвольно, считая количество символов "\n" до тех пор, пока не встретим символ EOF. EOF - это спецсимвол, который указывает на то, что ввод закончен и больше нет данных для чтения. Функция возвращает отрицательное значение в случае ошибки.
ЗАМЕЧАНИЕ: EOF имеет тип int, поэтому нужно использовать int для считывания символов. Кроме того, значение EOF не определено стандартом.

Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода . Выводимая информация записывается в поток, вводимая информация считывается из потока.

Когда поток открывается для ввода-вывода, он связывается со стандартной структурой типа FILE, которая определена в stdio.h. Структура FILE содержит необходимую информацию о файле.

Открытие файла осуществляется с помощью функции fopen(), которая возвращается указатель на структуру типа FILE, который можно использовать для последующих операций с файлом.

FILE *fopen(name, type);

name – имя открываемого файла (включая путь),
type - указатель на строку символов, определяющих способ доступа к файлу:

§ "r" - открыть файл для чтения (файл должен существовать);

§ "w" - открыть пустой файл для записи; если файл существует, то его содержимое теряется;

§ "a" - открыть файл для записи в конец (для добавления); файл создается, если он не существует;

§ "r+" - открыть файл для чтения и записи (файл должен существовать);

§ "w+" - открыть пустой файл для чтения и записи; если файл существует, то его содержимое теряется;

§ "a+" - открыть файл для чтения и дополнения, если файл не существует, то он создаётся.

Возвращаемое значение - указатель на открытый поток. Если обнаружена ошибка, то возвращается значение NULL.

Функция fclose() закрывает поток или потоки, связанные с открытыми при помощи функции fopen() файлами. Закрываемый поток определяется аргументом функции fclose().

Возвращаемое значение: значение 0, если поток успешно закрыт; константа EOF, если произошла ошибка.

#include
int main() {

char name="my.txt";

if(fp = fopen(name, "r")!=NULL) { // открыть файл удалось?
... // требуемые действия над данными

} else printf("Не удалось открыть файл");

Чтение символа из файла :

char fgetc(поток);

Аргументом функции является указатель на поток типа FILE. Функция возвращает код считанного символа. Если достигнут конец файла или возникла ошибка, возвращается константа EOF.
Запись символа в файл :

fputc(символ,поток);

Аргументами функции являются символ и указатель на поток типа FILE. Функция возвращает код считанного символа.

Функции fscanf() и fprintf() аналогичны функциям scanf() и printf(), но работают с файлами данных, и имеют первый аргумент - указатель на файл.

fscanf(поток, "ФорматВвода", аргументы);
fprintf(поток, "ФорматВывода", аргументы);

Функции fgets() и fputs() предназначены для ввода-вывода строк, они являются аналогами функций gets() и puts() для работы с файлами.

fgets(УказательНаСтроку,КоличествоСимволов,поток);

Символы читаются из потока до тех пор, пока не будет прочитан символ новой строки "\n", который включается в строку, или пока не наступит конец потока EOF или не будет прочитано максимальное символов. Результат помещается в указатель на строку и заканчивается нуль- символом "\0". Функция возвращает адрес строки.

fputs(УказательНаСтроку,поток);

Копирует строку в поток с текущей позиции. Завершающий нуль- символ не копируется.
Пример Ввести число и сохранить его в файле s1.txt. Считать число из файла s1.txt, увеличить его на 3 и сохранить в файле s2.txt.

#include
#include
int main() {

system("chcp 1251");

printf("Введите число: ");

scanf("%d", &x);

S1 = fopen("S1.txt", "w");

fprintf(S1, "%d", x);

S1 = fopen("S1.txt", "r");

S2 = fopen("S2.txt", "w");

fscanf(S1, "%d", &y);

fprintf(S2, "%d\n", y);

Результат выполнения - 2 файла

могу тебе в продолжение статьи посоветовать — обзавестись функциями (к примеру, функция записи в переменные, функция записи в файл, функция чтения из файла), так же сейчас столкнулся с проблемой — записи файла в одну переменную, т.е ты читаешь построчно и заносишь в разные переменные, а я хочу считать всё в одну переменную с динамическим выделением памяти по переменную…и ещё, что бы повеселиться — создай класс и уже в нём опиши функции обработки данных…если интересно, могу выложить исходник…

Сорри, потом только увидел, что ты пошёл намного дальше) очень интересно будет почитать тебя)

http://juniordeveloperad.blogspot.com/2012/04/junior-c-deloper-hi.html Вот, смотри. Я не знаю твоей мотивации и откуда ты берёшь свои азы…К примеру, по ссылке выложены задания по первой части предмета объектно-ориентированное программирование одного ииз Вузов. Могу скинуть на мыло книжку, по которой учаться студенты (её, конечно, не хватает). Про указатели скажу одно — надо разбираться. Для меня они остаются не до конца разобранными, но пользуюсь. Начал их разбирать с си. Там намного больше они участвуют в жизнедеятельности прилаги, там вообще больше ориентированно на работу с памятью. А потом перешёл на с++ и здесь опять же указатели. Многие говорят, что в с# они будут не нужны…Но я всё равно стараюсь разобраться и использовать их по максимуму 🙂 всё приходит с опытом.Кстати, в java нету указателей) Да и работа с памятью облегчена)По поводу контактов — не против, но icq не пользую. скайп скину на почту.

:
как С не С++, так и С++ не C#. java тоже – это java. К теме изучения C++ это не относится. Скорее это плюсы и минусы языков, поводы для дискуссий на форумах. по поводу книжки. может кому-то это тоже интересно и лучше дать автора и название книги сюда, чем лично мне

И еще по поводу вашей ссылки я постараюсь не спорить с вами ни тут ни там, просто скажу что думаю «Начинать надо с потяжелее» – лично я считаю совершенно по другомуСтрауструп писал, что чем больше вы знаете С, тем сложнее будет перейти на С++, используя преимущества C++ (не дословно). Вы держитесь противоположной идеологии и это полностью ваше право.

http://alfoot.net/lucik_op.doc книга преподавателей беларуского профильного вуза



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: