Какой из следующих классов обрабатывает процесс записи в файл

Обновлено: 05.07.2024

Респект Harry - смотрю, часто отвечает. Плиз, поясните, а почему вообще возникает проблема со считыванием полей класса string? Подозреваю, из-за непредсказуемой длины строк, но хотелось бы знать точно.

Именно поэтому Harry советует записывать предварительно длину в инт/переменную и считывать каждое поле класса отдельно?

И еще одно уточнение - значит, методы write/read из библиотек fstream'а можно использовать только для классов со стандартными полями (типа int, double) а для string и char* нужно писать переопределённые методы/друж-функции?

Есть такое понятие - сериализация. Как раз и занимается тем что превращает объекты в нечто, что можно записать в файл, а потом оттуда восстановить. Можно, например, сериализовать в JSON, и записывать в текст, а можно использовать Google Protobuf, и тогда в бинарном виде сохранить объект Строку - если это чисто текстовая строка - можно и писать-читать до нулевого заключительного символа. Но string в общем случае может содержать и нулевые символы. Поэтому приходится хранить и длину строки, и содержимое.

Давайте рассмотрим, что такое класс string, но в пока в идеализированном состоянии. Это просто структура, которая хранит размер строки, указатель на нее и емкость строки (то есть, реальный размер буфера, на который указывает строка).

В этот момент уже должно быть тревожно - там есть указатель! И сохраняя просто переменную типа string в файл как структуру (а ее размер оказывается обычно 32 байта), мы сохраняем размер, емкость (capacity) и указатель. После перезапуска программы этот указатель будет показывать в пустоту или куда то, где об этом не будут знать.

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

Почему иногда это все таки работает, не смотря на указатель? Во первых, часто тестируют не закрывая программу. В этом случае есть большая вероятность (ещё раз - гарантий нет, а только вероятность), что данные по указателю не будут испорчены.

Во вторых, есть такая штука, как SSO - small string optimization - оптимизация маленьких строк. Если строка небольшого размера (5-10 символов), то ее можно вместить прямо внутри структуры там, где хранится указатель-емкость. В теории можно запихнуть до 31 байта (если вся структура 32 байта - один битик нужен как флажок). И вот такая строка должна сохраниться и восстановится нормально - у нее нет "внешних буферов".

Теперь перейдем ближе к вопросу. Так как размер string в байтах не меняется (а иначе было бы невозможно объявить переменную класса типа string - компилятор бы не знал, сколько памяти выделять), то и при десериализации нужно знать размер строки, чтобы знать, сколько читать.

методы write/read из библиотек fstream'а можно использовать только для классов со стандартными полями (типа int, double) а для string и char* нужно писать переопределённые методы/друж-функции?

этими функциями можно писать pod типы. А string таким не является. (точнее, он иногда может быть таким - sso). По другому - если переменные класса не являются явными или неявными указателями (класс/структура имеет внешние данные), то для такого типа нужно писать специализированный сериализатор/десериализатор).

Существует файл «test.dat» в котором записано «Hello World».Каково будет содержимое файла после выполнения кода:

  • (Правильный ответ) .
  • Hello World.
  • Hello World

Вызовет ли данный код ошибку компиляции?

  • да, имя деструктора не может начинаться с маленькой буквы
  • нет, все записано верно
  • (Правильный ответ) да, имя деструктора должно совпадать с именем класса

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

  • (Правильный ответ) воспользоваться специальным манипулятором endl
  • при выводе строки символов перевод строки добавляется автоматически
  • закончить оператор точкой с запятой

Какой будет результат выполнения следующего кода?

В каком случае описание класса верно?

  • в третьем
  • (Правильный ответ) в первом
  • во втором

Функция вычисляет произведение двух чисел. Исходные данные вводятся с клавиатуры. Какие проверки целесообразно ввести в программе?

  • проверка, что исходные данные являются числами и эти числа больше нуля
  • (Правильный ответ) проверка, что исходные данные являются числами
  • проверка исходных данных на равенство нулю
  • проверки не нужны, все возможные ошибки отловит компилятор

Что выведет программа в стандартный поток вывода?

Для чего предназначен оператор namespace ?

  • для заключения в группу объявлений классов, переменных и функций для использования только в текущем модуле
  • (Правильный ответ) для заключения в группу объявлений классов, переменных и функций в отдельный контекст со своим именем
  • для использования классов, переменных и функций из других модулей программы без использования заголовочных файлов

Какие компоненты могут входить в интегрированную среду программирования

  • (Правильный ответ) компилятор
  • (Правильный ответ) текстовый редактор
  • (Правильный ответ) отладчик

Укажите все ключевые слова в приведенном примере?

int calc(int a, int b, bool f)

  • (Правильный ответ) int,bool,if,else,return
  • int,calc,bool,return,if,else
  • int,if,else,return

Если определена операция вычитания для двух объектов класса A , а операция преобразования к int не определена, что будет вызвано при

A a1,a2,a3=5;a3 = a1 – a2;

  • только операция вычитания
  • преобразование к целому
  • (Правильный ответ) произойдет ошибка
  • операция вычитания, а затем преобразование к целому

Шаблон A и его специализации объявлены следующим образом:

Какой будет результат после выполнения кода

  • ошибка компиляции в строке «template <> class A<int>»
  • 2 3 1
  • 1 1 1
  • (Правильный ответ) 2 1 1

Что будет на экране после выполнения программы

Какой из наборов перечисляемых значений записан правильно?

  • в различии использования заголовочных и исходных файлов
  • нет различий
  • (Правильный ответ) различие заключается в методе поиска препроцессором включаемого файла

Чему будет равен результат вычисления выражения: int d=5; bool b = true, c; c = (!b||(d>3));

  • (Правильный ответ) true
  • Ошибка компилятора
  • false

Если в арифметическом выражении участвуют целый и вещественный операнды, то:

  • (Правильный ответ) целый тип приводится к вещественному
  • ошибка компиляции
  • вещественный тип приводится к целому

Что будет выведено в результате выполнения данного кода?

Что будет на экране после выполнения программы

  • (Правильный ответ) Exception 3 0
  • Ошибка компиляции
  • Exception
  • 4 0

Для чего предназначен фрагмент текста из заголовочного файла:

  • (Правильный ответ) для защиты от повторного включения файла test.h
  • для определения символьной константы Test
  • для целей отладки
  • для защиты от удаления
  • для защиты от копирования

Укажите в каком выражении произойдет потеря точности

  • (Правильный ответ) int i; float x = 2.134, y = 3.14; i = x/y;
  • float M = 235.2; double Z = 3; Z *= M;
  • short i = 0x3; float x = 2.7, v; v = i + x;

Какой результат будет у следующего выражения?

  • hellohello
  • h
  • (Правильный ответ) ошибка компиляции
  • hello

Если после выражения стоит точка с запятой, то

  • выражение вычисляется только если первой стоит операция присваивания
  • (Правильный ответ) это оператор-выражение, действие которого заключается в вычислении выражения
  • выражение вычисляется, а его значение запоминается в специальной переменной, которую можно использовать в следующем операторе

Что из себя представляет динамическое выделение памяти?

  • (Правильный ответ) память под объект (переменную) может выделяться не сразу, а в процессе работы программы, освобождение памяти производится вручную
  • память под объект (переменную) выделяется каждый раз при обращении к переменной
  • память под объект (переменную) может выделяться не сразу, а в процессе работы программы, освобождение памяти производится автоматически после завершения программы

Отметьте истинные высказывания:

  • переменная инициализируется, потом объявляется
  • (Правильный ответ) переменная объявляется, потом изменяется
  • переменная объявляется, потом инициализируется и изменяется

Какой правильный вариант описания шаблона семейства классов?

  • template class Array
  • (Правильный ответ)
    template <class T>class Array;
  • template (class T)class Array;

Какие операции поддаются перегрузке?

  • только унарные
  • (Правильный ответ) унарные и бинарные
  • только бинарные

В каком случае программа выведет строку на консоль

Если в программе уже имеется функция с прототипом int func(int k, double f) , то какое из следующих объявлений не вызовет ошибки компиляции?

  • void func(int m, double g = 3.14)
  • (Правильный ответ) int func(double x, int y)
  • double func(int m, double g)

С помощью какого метода можно изменить текущую позицию в файле?

Какой результат будет у следующего выражения?

  • Exception 1Exception 2Exception 3
  • Exception 3
  • Exception 2
  • Exception 1Exception 2
  • (Правильный ответ) Exception 1

Какой правильный вызов функции базового класса из объекта производного класса, если в производном классе эта функция была замещена?

  • (Правильный ответ) Base::FunctionName();
  • FunctionName();
  • Base.FunctionName();
  • такую функцию вызывать нельзя.

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

  • последовательность выполнения функций определяется компилятором
  • все функции выполняются одновременно
  • (Правильный ответ) после выполнения одной функции управление переходит к следующей

Что будет напечатано в результате выполнения следующего кода?

Функция объявлена как friend класса. Отметьте верное.

  • (Правильный ответ) функция имеет доступ к внутренним атрибутам класса
  • ключевое слово friend не оказывает влияния на функции и операторы
  • функция-оператор должна иметь в качестве первого аргумента объект данного класса

Какой результат будет у следующего выражения?

int m = 1, n=2; double A = (double)m/n; cout << A;

В каких случаях код будет работать правильно

  • (Правильный ответ) если оператор [] переопределен соответствующим образом
  • если существует элемент IntVector[0]
  • ничего, так как эта запись ошибочна

Процесс компиляции программы

  • приводит программы к единообразному внешнему виду
  • (Правильный ответ) переводит исходный текст в исполняемый файл
  • для языка Си++ необязателен

Какой массив имеет самый большой размер?

  • s3
  • s1
  • (Правильный ответ) Все массивы имеют одинаковый размер
  • s2

Существует файл «c:\test.dat» в котором записано «Hello World».Каково будет содержимое файла после выполнения кода:

Является ли x переменной или константой?

  • является константой
  • (Правильный ответ) определить нельзя
  • является переменной

Что описывает данная строка программы: float mas=new int[3][2] ?

  • (Правильный ответ) данная строка представляет собой ошибочную запись и работать не будет
  • создание одномерного динамического массива из 3 элементов
  • создание двумерного динамического массива размерности 3*2
  • создание одномерного динамического массива из 2 элементов

Может ли нестатический метод иметь доступ к статическим методам и атрибутам?

  • не может
  • (Правильный ответ) может

Отметьте все утверждения, которые считаете верными:

  • (Правильный ответ) в качестве описания шаблона функции используется прототип шаблона: template <список _параметров _шаблона >
  • (Правильный ответ) цель введения шаблонов – создание функций, которые могут обрабатывать разнотипные данные
  • нельзя с помощью шаблона создать функцию с таким же именем, как у явно определенной функции

Определите результат выполнения следующего кода:

float *thingPtr = new float (3.14159)

  • возникнет ошибка компиляции, поскольку нельзя задавать значение переменной в процессе её создания
  • (Правильный ответ) данная строка задает значение объекту типа float
  • возникнет ошибка компиляции, поскольку при создании объекта не указан размер выделяемой памяти

Если в арифметическом выражении участвуют короткое целое и длинное целое, то:

  • ошибка компиляции
  • длинное приводится к короткому
  • (Правильный ответ) короткое приводится к длинному

Что будет выведено на экран?

Чему равно значение выражения !((1 || 0) && 0) ?

  • ошибка компиляции
  • 0
  • (Правильный ответ) 1

Может ли статический метод класса быть объявлен как friend ?

  • не может
  • (Правильный ответ) может

Если int n=3 , какой будет результат ?

  • ошибка компилятора
  • ввв
  • ааа
  • (Правильный ответ) ббб
  • неопределенное поведение

С помощью механизма friend можно разрешить обращение к внутренним элементам класса:

  • (Правильный ответ) всем методам другого класса
  • (Правильный ответ) отдельной функции
  • (Правильный ответ) отдельному методу другого класса

Что вычисляет эта функция:

  • факториал
  • любую степень любого числа
  • (Правильный ответ) целую степень любого числа
  • дробную степень вещественного ненулевого числа

Укажите какому классу принадлежит атрибут Z1

  • обоим классам
  • классу t
  • (Правильный ответ) запись неверна

Что будет выведено на экран в результате выполнения кода?

Что будет на экране после выполнения программы

  • ошибка компиляции
  • Exception 4 0
  • Exception
  • (Правильный ответ) Exception 3 0

Если функция вычисления факториала n имеет прототип int fact(int n) , отметьте код, использующий рекурсию и правильно вычисляющий значение факториала:

В каком случае компилятор выдаст ошибку:

  • (Правильный ответ) int int iCeloe;
  • bool LD1LW;
  • (Правильный ответ) const float fL = 32; float e23 = 1; fL = e23;

Известно, что в классе A определен один публичный конструктор A(int); . Выберите из предложенных выражений компилируемые:

  • A *a(4);
  • A a;
  • (Правильный ответ) A *a = new A(4);
  • (Правильный ответ) A a(4);

Определите размер структуры

Укажите правильный идентификатор для имени переменной:

Если есть два объявления int qwerty; int QWERTY; какое из
утверждений верно

  • такие имена переменных недопустимы
  • (Правильный ответ) объявления правильные
  • такие объявления недопустимы, так как мы пытаемся создать две одинаковые переменные

Какой статус международного стандарта языка Си++?

  • (Правильный ответ) принят ISO и тем самым автоматически принят во всех странах
  • принят проект стандарта, дорабатывается
  • принят только в США и ждет одобрения международной организации

Битовой операцией является

Какой результат будет у следующего выражения?

  • Exception 1Exception 2Exception 3
  • Exception 1
  • Exception 1Exception 2
  • (Правильный ответ) Exception 2
  • Exception 3

Какое из следующих объявлений является объявлением неизменяемого указателя?

  • (Правильный ответ) int* const ptr;
  • const int* ptr;
  • int * ptr const;
  • int const* ptr;

Допустима ли следующая конструкция?

  • произойдет ошибка компиляции
  • (Правильный ответ) допустима
  • произойдет ошибка при выполнении

Будет ли вызываться конструктор, если в программе встретится следующaя конструкция:

monstr Super(200, 300), Vasia(50), Z;monstr X = monstr(1000);monstr Y = 500;

  • (Правильный ответ) да, будет
  • нет, не будет
  • данный код вызовет ошибку компиляции
  • данная конструкция содержит синтаксическую ошибку

Что понимается под потоком в языке C++

  • обмен данными между программами
  • (Правильный ответ) механизм ввода-вывода
  • обмен данными между компилятором и функцией main

Что будет выведено в результате выполнения следующего кода?

int a[4] = < 1,2,3,4>; int* p = a; cout << (*p+2) + *p;

Что будет на экране после выполнения программы

  • Exception 4 0
  • (Правильный ответ) 4 0
  • Exception
  • Exception 3 0

Могут ли контексты быть вложенными?

  • могут, при определенных условиях
  • не могут
  • (Правильный ответ) могут

Что будет на экране после выполнения данного кода

  • результат невозможно предсказать
  • 1234
  • код не выполнится из-за ошибки компиляции
  • (Правильный ответ) 1234 и случайное число

Чему равен результат вычисления выражения

при x = 12 и b = 8 ?

Если имеется код

как обратиться к переменной a ?

В каких выражениях правильно определен метод класса Ping ?

  • Ping::MathFunc(double D)
  • (Правильный ответ) void Ping::MathFunc(double D)
  • (Правильный ответ) void Ping::MathFunc(double D)

В чем заключается принцип полиморфизма?

  • в использовании виртуального наследования
  • (Правильный ответ) в наличии виртуальных методов
  • в наличии множественного наследования

Какие бывают конструкторы?

  • инициализирующий
  • (Правильный ответ) по умолчанию
  • (Правильный ответ) с параметрами
  • (Правильный ответ) копирующий

Какой результат следующего выражения ?

int *a; int b[2]; a = b; b[0] = 7; b[1] = 10; *a++; cout << *a;

Что является результатом компоновки программы?

  • набор заголовочных файлов с определением в них всех используемых функций
  • (Правильный ответ) исполняемый файл или библиотека
  • заголовочный файл

Если имеется объявление char ch1=’a’,ch2=’b’,ch3=’c’;
допустима ли запись ch1=ch2+ch3;

Если объявлен тип

сколько байтов занимает один объект такого типа?

Если функция вычисления суммы целых чисел от 1 до n имеет прототип int sum(int n) , запишите определение функции, используя рекурсию:

Что происходит при попытке выполнить оператор return внутри блока catch ?

  • (Правильный ответ) выход из функции
  • повторное создание обрабатываемой исключительной ситуации
  • ошибка компиляции
  • аварийная остановка программы
  • ошибка выполнения

Чему равен результат вычисления выражения

при x = 12 и b = 8 ?

Что выполняет операция «delete [] v;» в данном ниже коде:

MyClass (); int&operator [] ( int index ); // операция индексации >;…MyClass::

Дан файл «Input.txt», в котором каждая строка имеет значения, аналогичные переменным экземпляра класса.
Прочитайте значения в объект класса и выполните необходимые операции.

using namespace std;


// Класс для определения свойств

int Age, Ratings;

// Объявление функции input () для ввода информации

// Объявление функции output_highest_rated () для

// извлекать информацию из файла базы данных


// Определение функции input () для ввода информации

// Объект для записи в файл

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

file_obj.open( "Input.txt" , ios::app);

// Объект участника класса для ввода данных в файл

// Подача соответствующих данных в переменные

string str = "Micheal" ;

int age = 18, ratings = 2500;

// Назначение данных в объект

// Запись данных объекта в файл

file_obj.write(( char *)&obj, sizeof (obj));

// Подача соответствующих данных в переменные

// Назначение данных в объект

// Запись данных объекта в файл

file_obj.write(( char *)&obj, sizeof (obj));


// Определение функции output_highest_rated () для
// извлекать информацию из файла базы данных

// Объект для чтения из файла

// Открытие файла в режиме ввода

file_obj.open( "Input.txt" , ios::in);

// Объект участника класса для ввода данных в файл

// Чтение из файла в объект "obj"

file_obj.read(( char *)&obj, sizeof (obj));

// максимум, чтобы сохранить максимальные оценки

// Highest_rated хранит имя участника с самым высоким рейтингом

// Проверяем, пока у нас нет корма

// Назначаем максимальные рейтинги

if (obj.Ratings > max)

file_obj.read(( char *)&obj, sizeof (obj));

// Выход - участник с самым высоким рейтингом

// Создание объекта класса

// Извлечение участника с максимальным рейтингом

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

DirectoryInfo

Для работы с каталогами удобнее всего использовать класс DirectoryInfo. Рассмотрим основные члены это класса:

Чтобы начать работу с DirectoryInfo, нужно создать новый объект этого типа, указав каталог, с которым вы будете работать:

Указать можете, как существующий, так и несуществующий каталог. Если вы пытаетесь привязаться к несуществующему каталогу, то будет сгенерировано исключение System.IO.DirectoryNotFoundException. Если нужно создать несуществующий каталог, то укажите перед его именем знак @, например:

Классы Directory и DriveInfo

Рассмотри пример (выведем список дисков вашего компьютера):

Метод GetLogicalDrivers() возращает массив строк, а не массив объектов DirectoryInfo. Также метод вызывается без предварительного создания объекта оператором new. Данный метод сообщает буквы логических дисков, при этом невозможно понять, где и какой диск.

Если нужно получить больше информации о дисках, нужно использовать тип DriveInfo:

FileInfo

Класс FileInfo используется для манипуляции с файлами.Рассмотрим его основные члены(методы):

Create()

Создает новый файл и возвращает объект FileStream, который используется для взаимодействия с созданным файлом.

CreateText()

Создает объект StreamWriter, который используется для создания текстового файла.

CopyTo()

Копирует существующий файл в другой файл.

AppendText()

Создает объект StreamWriter для добавления текста в файл.

Delete()

Удаляет файл, связанный с экземпляром FileInfo

Directory

Используется для получения экземпляра родительского каталога

DirectoryName

Содержит полный путь к родительскому каталогу

Length

Получает размер текущего файла или каталога.

MoveTo()

Используется для перемещения файла.

Содержит имя файла.

Открывает файл с различными разрешениями чтения/записи.

OpenRead()

Создает доступный только для чтения объект FileStream.

OpenText()

Создает объект StreamReader для чтения информации из текстового файла.

OpenWrite()

Создает объект FileStream, доступный только для записи

Примеры использования класса FileInfo:

Использование метода Create():

Тут создаётся поток FileStream, позволяющий производить манипуляции с содержимым файла, например, читать из него данные, записывать в него данные.

Аналогично, метод ReadAllBytes() читает все байты из файла, возвращает массив байтов и закрывает файл.

Метод ReadAllText() читает все содержимое текстового файла в одну строку и возвращает её. Как обычно, файл после чтения будет закрыт.

Существует и аналогичные методы записи WriteAllBytes(), WriteAllLines() и WriteAlltext(), которые записывают в файл, соответственно, массив байтов, массив строк и строку. После записи файл закрывается. Рассмотрим пример:

Stream

В абстрактном классе System.IO.Stream определен набор членов, которые обеспечивают поддержку синхронного и асинхронного взаимодействия с хранилищем (например, файлом или областью памяти). Члены абстрактного класса:

CanRead, CarWrite, CanSeek

Определяют, поддерживает ли поток чтение, запись и поиск.

Close()

Метод закрывает поток и освобождает все ресурсы.

Flush()

Метод обновляет лежащий в основе источник данных. Напимер, позволяет перечитать источник.

Length

Возвращает длину потока в байтах.

Position

Определяет текущую позицию в потоке.

Read(), ReadByte()

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

Устанавливает позицию в текущем потоке.

SetLength()

Устанавливает длину текущего потока.

Write(), WriteByte()

Записывает последовательность байтов или одиночный байт в текущий поток и перемещает текущую позицию на количество записанных байтов.

FileStream

Класс FileStream предоставляет реализацию абстрактного члена Stream для потоковой работы с файлами. Это элементарный поток, и он может записывать или читать только один байт или массив байтов.

Классы StreamWriter и StreamReader

Данные классы удобно использовать во всех случаях, когда нужно читать или записывать символьные данные. Оба типа работают по умолчанию с символами Unicode, но кодировку можно изменить предоставлением правильно сконфигурированной ссылки на объект System.Text.Encoding. Пример записи в файл с использованием StreamWriter:

Пример чтения информации из текстового файла с помощью StreamReader:

Классы BinaryWriter и BinaryReader

Метод Flush() у BinaryWriter позволяет сбросить буфер двоичного потока на носитель. Пример использования:

Читайте также: