Skip to content

Instantly share code, notes, and snippets.

@ramntry
Created October 14, 2011 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ramntry/1288101 to your computer and use it in GitHub Desktop.
Save ramntry/1288101 to your computer and use it in GitHub Desktop.
Reading file from c- and cpp-code in c-, cpp- and stl-style
/**
* Чтение из файла в С
*/
#include <stdio.h>
#define MAX_SIZE 1024
int main()
{
FILE * fd = fopen("file_name.txt", "r"); /// Второй аргумент - режим
if (!fd) /// открытия файла (1):
{ /// r - чтение из существующего файла
printf("File not found\n"); /// w - создание файла и запись в него
return 1; /// (с перезаписью существующего)
} /// a - дозапись в конец существующего
/// (или создание файла)
int array[MAX_SIZE];
int size = 0;
while (size < MAX_SIZE && fscanf(fd, "%d", &array[size]) != EOF)
size++; // контроль границ // контроль границ
// массива-приемника // файла-источника
// здесь size действительно содержит количество считанных int
fclose(fd); /// закрытие файла
int i = 0;
for (; i < size; i++)
printf("%d ", array[i]);
putchar('\n');
return 0;
}
/**
* (1)
* Полная форма режима открытия файла имеет вид
* "nme"
* где n - r, w или a
* m - t (текстовый режим открытия файла (по умолчанию) - включает
* эмуляцию *nix-ового конца строки ('\n'), выполняет некоторые
* другие преобразования с читаемым из файла потоком)
* b (бинарный режим - представляет файл "как есть")
* e - + (дополнительно к n разрешить все остальные операции)
*
* Например "ab+" проверит, есть ли указанный файл в директории, если
* нет - создаст его и установит курсор файла в его начало, если есть -
* откроет файл и установит курсор в конец так, что любая запись в файл
* будет равносильна дозаписи в его конец. Режим доступа - бинарный (без
* эмуляций), чтение - разрешено.
*/
/**
* Чтение из файла в c++ в стиле C
*/
#include <stdio.h>
int main()
{
const int maxSize = 1024; // уход от директив define к константам
FILE * fd = fopen("file_name.txt", "r");
if (!fd)
{
printf("File not found\n");
return 1;
}
int array[maxSize];
int size = 0;
while (size < maxSize && fscanf(fd, "%d", &array[size]) != EOF)
size++;
fclose(fd);
for (int i = 0; i < size; i++) // гарантированная поддержка объявления
printf("%d ", array[i]); // переменных в заголовке цикла
putchar('\n');
return 0;
}
/**
* Чтение из файла в С++ в стиле C
*
* Продвинутый вариант с попыткой уйти от ограничений
* по максимальному размеру считываемого массива
*
* Версия 1 - экономно по скорости, расточительно - по памяти
* (дублирование в стиле C++ затруднительно - нет аналога realloc)
*/
#include <stdio.h>
#include <stdlib.h> // для malloc, realloc, free
int fsize(FILE * fd) // Определить размер файла - нетривиальная
{ // задача, особенно кроссплатформенно. Здесь:
int cur = ftell(fd); // сохранить текущую позицию в файле (2)
fseek(fd, 0, SEEK_END); // переместиться в конец файла
int size = ftell(fd); // выяснить размер
fseek(fd, cur, SEEK_SET); // вернуть файловый курсор на место
return size;
}
int main()
{
FILE * fd = fopen("file_name.txt", "r");
if (!fd)
{
printf("File not found\n");
return 1;
}
// максимально возможное количество числовых значений в файле
int maxSize = (fsize(fd) + 1) / 2;
// выделение области динамической памяти для размещения в ней
// массива из maxSize элементов sizeof() байт размером каждый
// (malloc возвращает нетипизированный указатель типа void*,
// который необходимо привести к int*)
//
int * array = (int*) malloc(maxSize * sizeof(int));
if (!array)
{
printf("Not enough memory\n");
return 2;
}
int size = 0;
while (size < maxSize && fscanf(fd, "%d", &array[size]) != EOF)
size++;
fclose(fd);
// Перераспределение памяти с целью освободить избыточный резерв
// (теперь известен реальный размер массива)
array = (int*) realloc(array, size * sizeof(int));
for (int i = 0; i < size; i++)
printf("%d ", array[i]);
putchar('\n');
free(array); // освобождение памяти
return 0;
}
/**
* (2)
* Существует понятие курсора в файле - он указывает на позицию, с
* с которой и будет осуществляться следующая операция с файлом -
* чтение, запись или усечение. Чтение или запись сдвигает курсор
* к концу файла. Получить текущую позицию курсора можно функцией
* ftell(FILE * fd), а установить позицию вручную - функцией
* fseek(FILE * fd, int offset, int from), где
* from - откуда вести отсчет (SEEK_SET - от начала файла,
* SEEK_CUR - от текущей позиции,
* SEEK_END - от конца файла)
* offset - смещение относительно from
*/
/**
* Чтение из файла в С++ в стиле C
*
* Продвинутый вариант с попыткой уйти от ограничений
* по максимальному размеру считываемого массива
*
* Версия 2 - медленнее, но экономнее по памяти
* (дублирование в стиле C++ возможно - не используется realloc)
*/
#include <stdio.h>
#include <stdlib.h> // для malloc, free
int fsize_int(FILE * fd) // определим, сколько в файле int
{
int cur = ftell(fd); // запомним текущую позицию в файле
int size = 0;
while (fscanf(fd, "%*d") != EOF) // * - считывать и пропускать
size++;
fseek(fd, cur, SEEK_SET); // восстановим позицию в файле
return size;
}
int main()
{
FILE * fd = fopen("file_name.txt", "r");
if (!fd)
{
printf("File not found\n");
return 1;
}
int size = fsize_int(fd);
// выделение области динамической памяти для размещения в ней
// массива из size элементов sizeof() байт размером каждый
// (malloc возвращает нетипизированный указатель типа void*,
// который необходимо привести к int*
//
int * array = (int*) malloc(size * sizeof(int));
if (!array)
{
printf("Not enough memory\n");
return 2;
}
for (int i = 0; i < size; i++) // ничего проверять не нужно -
fscanf(fd, "%d", &array[i]); // актуальный size уже получен
fclose(fd);
for (int i = 0; i < size; i++)
printf("%d ", array[i]);
putchar('\n');
free(array); // освобождение памяти
return 0;
}
/**
* Чтение из файла в С++
*/
#include <iostream>
#include <fstream>
using namespace std; // глобальное разрешение области видимости
// пространства имен std - дабы избежать конструкций
int main() // вида std::ifstream, std::cerr, std::endl и т. д.
{
const int maxSize = 1024;
ifstream in("file_name.txt"); // создание файлового потока на чтение
if (!in)
{
cerr << "File not found" << endl; // cerr - стандартный поток
return 1; // ошибок; 1 - код возврата
} // (передается ОС)
int array[maxSize];
int size = 0;
in >> array[size]; // в случае неудачного чтения в ifstream
while (size < maxSize && in) // поднимается флаг ошибки
in >> array[++size]; // именно прединкремент - это важно
in.close();
for (int i = 0; i < size; i++)
cout << array[i] << ' ';
cout << endl;
return 0; // код возврата со значением "все прошло успешно" - 0
}
/**
* Чтение из файла в C++ с использованием STL
*/
#include <iostream> // Многие из заголовочников могут быть избыточными,
#include <fstream> // но это зависит от выбора компилятора и лучше
#include <vector> // указать все.
#include <iterator> // для istream_iterator
#include <algorithm> // для copy
using namespace std;
int main()
{
ifstream in("file_name.txt");
if (!in)
{
cerr << "file not found" << endl;
return 1;
}
vector<int> vint; // создание вектора - "продвинутого массива с
// резиновыми границами" - на int
istream_iterator<int> iin(in); // установка итератора (мощного аналога
istream_iterator<int> eos; // указателя) на начало файла (iin) и
// объявление знака конца файла (eos)
// копирование из файла от начала и до конца в vint со вставкой
// (автоматическим увеличением размеров), начиная с нулевой позиции vint
copy(iin, eos, inserter(vint, vint.begin()));
in.close();
// копирование из вектора vint c начала и до конца (метод begin()
// возвращает объект типа vector<int>::iterator, установленный на
// нулевой элемент вектора, end() - на элемент за последним) в
// позицию, указанную итератором ostream_iterator (в данном случае
// указывающим в стандартный поток вывода, настроенный на вывод
// с пробелом в качестве символа-разделителя)
//
copy(vint.begin(), vint.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment