Класс string c функции и методы

Класс string c функции и методы

  • atomic (C++11)
  • condition_variable (C++11)
  • future (C++11)
  • mutex (C++11)
  • shared_mutex (C++14)
  • thread (C++11)
  • cassert
  • cctype
  • cerrno
  • cfenv (C++11)
  • cfloat
  • cinttypes (C++11)
  • ciso646
  • climits
  • clocale
  • cmath
  • csetjmp
  • csignal
  • cstdarg
  • cstdbool (C++11)
  • cstddef
  • cstdint (C++11)
  • cstdio
  • cstdlib
  • cstring
  • ctgmath (C++11)
  • ctime
  • cuchar (C++11)
  • cwchar
  • cwctype

string — класс с методами и переменными для организации работы со строками в языке программирования C++. Он включён в стандартную библиотеку C++. Название образовано от имени строчного типа данных (англ. string ; с англ. — «строка»). В языке C++ и его предшественнике, языке программирования Си, нет встроенной поддержки строкового типа данных, вместо этого используется массив символов. string управляет строками, как и string.h в Си. string использует единственный объект string для организации работы со строками. Являясь частью стандартной библиотеки C++, эти объекты также являются частью стандартного пространства имён — std.

Содержание

Пример [ править | править код ]

Простейшая программа «Hello, world!» (с использованием библиотеки iostream) может быть записана так:

Используемые типы [ править | править код ]

Тип Описание
value_type char
traits_type char_traits
allocator_type allocator
reference char&
const_reference const char&
pointer char*
const_pointer const char*
iterator a random access iterator to char (convertible to const_iterator)
const_iterator a random access iterator to const char
reverse_iterator reverse_iterator
const_reverse_iterator reverse_iterator
difference_type ptrdiff_t
size_type size_t

Методы [ править | править код ]

Конструктор [ править | править код ]

Создает пустую строку [1] .

Копирующий конструктор со смещением и определенной длиной считываемой строки [1] .

string(const char* s);

Конструктор, принимающий указатель на строку символов [1] .

string(const char* s, size_t n);

Конструктор, принимающий указатель на строку символов с ограничением по длине считываемой строки [1] .

string(size_t n, char c);

Конструктор, заполняющий одним символом n ячеек [1] .

template string(InputIterator first, InputIterator last);

Конструктор, копирующий последовательность символов в диапазоне [1] .

Конструктор, копирующий инициализирующий список [1] .

Конструктор, получающий содержимое строки [1] .

Деструктор [ править | править код ]

String destructor (public member function)

Оператор присваивания [ править | править код ]

Оператор реализующий присваивание переменной типа string [1] .

Оператор реализующий присваивание указателя на строку [1] .

Оператор реализующий присваивание переменной типа char [1] .

Оператор реализующий присваивание к списку инициализации из типов char [1] .

Оператор реализующий перемещение [ неопределённость ] содержания переменной внутрь левого значения [1] .

Итераторы [ править | править код ]

Возвращает итератор с первым элементом [1] .

Возвращает итератор с последним элементом [1] .

Возвращает итератор с последним элементом, но идущим в реверсивном порядке (от конца к началу) [1] .

Возвращает итератор с первым элементом, но идущим в реверсивном порядке (от конца к началу) [1] .

Возвращает константный итератор с первым элементом [1] .

Возвращает константный итератор с последним элементом [1] .

Возвращает константный итератор с последним элементом, но идущим в реверсивном порядке (от конца к началу) [1] .

Возвращает константный итератор с первым элементом, но идущим в реверсивном порядке (от конца к началу) [1] .

Методы [ править | править код ]

size_t size() const noexcept

Возвращает текущее количество символов в строке [1] .

size_t length() const noexcept

Возвращает текущее количество символов в строке [1] .

size_t max_size() const noexcept

Возвращает максимально возможную длину строки [1] .

void resize(size_t n);

Изменяет размер длины строки [1] .

void resize(size_t n, char c);

Изменяет размер длины строки и заполняет строку указанным символом [1] .

size_t capacity() const noexcept

Возвращает длину строки выделенной памяти [1] .

void reserve(size_t n = 0)

Резервирует память для n символов [1] .

void clear() noexcept

bool empty() const noexcept

Возвращает булев флаг о том, пуста ли строка [1] .

Элементы доступа [ править | править код ]

char& operator[] (size_t pos)

Возвращает символ находящийся по индексу в строке начиная с 0 до size() — 1 [1] .

const char& operator[] (size_t pos) const

Возвращает константный символ находящийся по индексу в строке начиная с 0 до size() — 1 [1] .

char& at (size_t pos)

Возвращает ссылку на символ, указанный в pos [1] .

const char& at (size_t pos) const

Возвращает константную ссылку на символ, указанный в pos [1] .

Возвращает ссылку на последний символ строки [1] .

const char& back() const

Возвращает константную ссылку на последний символ строки [1] .

Возвращает ссылку на первый символ строки [1] .

const char& front() const

Возвращает константную ссылку на первый символ строки [1] .

В современном стандарте C++ определен класс с функциями и свойствами (переменными) для организации работы со строками (в классическом языке C строк как таковых нет, есть лишь массивы символов char ):

Для работы со строками также нужно подключить стандартный namespace :

В противном случае придётся везде указывать описатель класса std::string вместо string .

Ниже приводится пример программы, работающей со string (в старых си-совместимых компиляторах не работает!):

Основные возможности, которыми обладает класс string :

  • инициализация массивом символов (строкой встроенного типа) или другим объектом типа string . Встроенный тип не обладает второй возможностью;
  • копирование одной строки в другую. Для встроенного типа приходится использовать функцию strcpy() ;
  • доступ к отдельным символам строки для чтения и записи. Во встроенном массиве для этого применяется операция взятия индекса или косвенная адресация с помощью указателя;
  • сравнение двух строк на равенство. Для встроенного типа используются функции семейства strcmp() ;
  • конкатенация (сцепление) двух строк, дающая результат либо как третью строку, либо вместо одной из исходных. Для встроенного типа применяется функция strcat() , однако чтобы получить результат в новой строке, необходимо последовательно задействовать функции strcpy() и strcat() , а также позаботиться о выделении памяти;
  • встроенные средства определения длины строки (функции-члены класса size() и l ength() ). Узнать длину строки встроенного типа можно только вычислением с помощью функции strlen() ;
  • возможность узнать, пуста ли строка.

Рассмотрим эти базовые возможности более подробно.

Инициализация строк при описании и длина строки (не включая завершающий нуль-терминатор):

Строка может быть задана и пустой:

Для проверки того, пуста ли строка, можно сравнить ее длину с 0:

или применить метод empty() , возвращающий true для пустой строки и false для непустой:

Читайте также:  Умные часы g100 детские отзывы

Третья форма создания строки инициализирует объект типа string другим объектом того же типа:

Строка st3 инициализируется строкой st . Как мы можем убедиться, что эти строки совпадают? Воспользуемся оператором сравнения ( == ):

Как скопировать одну строку в другую? С помощью обычной операции присваивания:

Для сцепления строк используется операция сложения ( + ) или операция сложения с присваиванием ( += ). Пусть даны две строки:

Мы можем получить третью строку, состоящую из конкатенации первых двух, таким образом:

Если же мы хотим добавить s2 в конец s1 , мы должны написать:

Операция сложения может сцеплять объекты класса string не только между собой, но и со строками встроенного типа. Можно переписать пример, приведенный выше, так, чтобы специальные символы и знаки препинания представлялись встроенным типом char * , а значимые слова – объектами класса string :

Подобные выражения работают потому, что компилятор "знает", как автоматически преобразовывать объекты встроенного типа в объекты класса string . Возможно и простое присваивание встроенной строки объекту string :

Обратное преобразование при этом не работает. Попытка выполнить следующую инициализацию строки встроенного типа вызовет ошибку компиляции:

Чтобы осуществить такое преобразование, необходимо явно вызвать функцию-член с названием c_str() ("строка Си"):

Функция c_str() возвращает указатель на символьный массив, содержащий строку объекта string в том виде, в каком она находилась бы во встроенном строковом типе. Ключевое слово const здесь предотвращает "опасную" в современных визуальных средах возможность непосредственной модификации содержимого объекта через указатель.

К отдельным символам объекта типа string , как и встроенного типа, можно обращаться с помощью операции взятия индекса. Вот, например, фрагмент кода, заменяющего все точки символами подчеркивания:

Но лучше читать документацию по C++ и пользоваться его возможностями. Например, предыдущее действие мы могли бы выполнить вызовом одной-единственной функции replace() :

Правда, здесь использован не метод replace класса string , а одноимённый алгоритм:

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

Ниже приводится краткое описание основных операторов и функций класса string , ссылки в таблице ведут к русскоязычным описаниям в интернете. Более полный список возможностей класса string можно получить, например, в Википедии или на сайте cplusplus.com.

Задание символов в строке

присваивает значения строке

назначает символы строке

Доступ к отдельным символам

получение указанного символа с проверкой выхода индекса за границы

получение указанного символа

получение первого символа

получение последнего символа

возвращает указатель на первый символ строки

возвращает немодифицируемый массив символов С , содержащий символы строки

Проверка на вместимость строки

проверяет, является ли строка пустой

возвращает количество символов в строке

возвращает максимальное количество символов

Работу с объектами поясним также на примере строк, которые традиционно можно воспринимать и как тип данных string, и как объекты класса String библиотеки System.

Тип данных string – псевдоним класса String, поэтому слово можно начинать как со строчной, так и прописной буквы.

С точки зрения программирования этот тип данных относится к числу самых важных в C#. Этот тип определяет и поддерживает символьные строки в кодировке Unicode (1 символ – 2 байта).

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

Объявление и инициализация строк

Также как массивы, строки необходимо объявлять и инициализировать. Объявление строк формально не отличается от объявления встроенных типов данных (например, int) или любых объектов:
string s1;

При объявлении только создается ссылка на строку, однако фактически строка не создается. Попытка обратиться к строке по ссылке приводит к стандартной ошибке:
Использование локальной переменной «s1», которой не присвоено значение.

Инициализация пустой строки может быть выполнена оператором:
s1 = string.Empty;
Чаще всего совмещают объявление и инициализацию строки:
string s1 = string.Empty;
В результате мы получим строку из 0 символов. Такая строка может использоваться для сравнения с другими строками или же, как начальная строка, к которой будут добавляться другие наборы символов.

Простой способ построить символьную строку — воспользоваться строковым литералом. Например, в следующей строке кода переменной ссылки на строку s2 присваивается ссылка на строковый литерал (последовательность символов, заключенных в двойные кавычки):
string s2 = «Пример строки»;
В данном случае переменная s2 инициализируется последовательностью символов «Пример строки».

Объект типа string можно также создать из массива типа char. Например:
char[] chararray = <‘e’, ‘x’, ‘a’, ‘m’, ‘p’, ‘l’, ‘e’>;
string s3 = new string(chararray);

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

В последнем варианте строка s3 объявляется и инициализируется явно как объект, где string( ) – конструктор класса с параметрами (имеет 8 перегрузок метода с разным количеством и типом параметров). Например, если необходимо создать строку из 60 одинаковых символов, например, подчеркиваний, то для этого достаточно выполнить следующий оператор:
string s4 = new String(‘_’, 60);

Изучите с помощью интеллектуальной подсказки все 8 перегрузок конструктора string(…).

Я предполагаю, что некоторое особое место строк как типов данных в языке C# связано с тем, что содержимое объекта типа string не подлежит изменению. Это означает, что однажды созданную последовательность символов изменить нельзя (напомним, что содержимое строк, как и любых объектов, располагается в управляемой куче).

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

А поскольку неиспользуемые строковые объекты автоматически собираются в «мусор», то о дальнейшей судьбе ненужных строк можно даже не беспокоиться.

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

Читайте также:  Менеджер сессий для firefox

Работа со строками. В классе System.String предоставляется набор методов для определения длины символьных данных, поиска подстроки в текущей строке, преобразования символов из верхнего регистра в нижний и наоборот, и т.д. Далее мы рассмотрим этот класс более подробно.

Поле, индексатор и свойство класса String

В классе String определено единственное поле:
public static readonly string Empty;
Поле Empty обозначает пустую строку, т.е. такую строку, которая не содержит символы. Этим оно отличается от пустой ссылки типа String, которая просто делается на несуществующий объект.

Помимо этого, в классе String определен единственный индексатор, доступный только для чтения:
public char this[int index]
Этот индексатор позволяет получить символ по указанному индексу.

Индексация символов в строке, как и элементов массива, начинается с нуля. Объекты типа String отличаются постоянством и не изменяются, поэтому вполне логично, что в классе String поддерживается индексатор, доступный только для чтения. Для извлечения пятого символа из строки s1 достаточно написать:
char ch = s1[4];

В классе String определено единственное свойство, доступное только для чтения:
public int Length
Свойство Length возвращает количество символов в строке.

В примере показано использование индексатора и свойства Length:

Операторы класса String

В классе String перегружаются два следующих оператора: == и !=.

Оператор == служит для проверки двух символьных строк на равенство. Когда оператор == применяется к ссылкам на объекты, он обычно проверяет, делаются ли обе ссылки на один и тот же объект. А когда оператор == применяется к ссылкам на объекты типа String, то на предмет равенства сравнивается содержимое самих строк.

Это же относится и к оператору !=. Когда он применяется к ссылкам на объекты типа String, то на предмет неравенства сравнивается содержимое самих строк.

В то же время другие операторы отношения, в том числе =, сравнивают ссылки на объекты типа String таким же образом, как и на объекты других типов. А для того чтобы проверить, является ли одна строка больше другой, следует вызвать метод Compare(), определенный в классе String (см.ниже).

Примечание. Как станет ясно дальше, во многих видах сравнения символьных строк используются сведения о культурной среде. Но это не относится к операторам == и !=. Они просто сравнивают порядковые значения символов в строках. (Иными словами, они сравнивают двоичные значения символов, не видоизмененные нормами культурной среды, т.е. региональными стандартами.) Пример регионального стандарта: точка-запятая в записи действительных (не целых) чисел — В России в школе пишем число Пи = 3,14 — на Западе 3.14 ; у них 345,123 соответствует нашим 345 123 (у них разделитель «,» — у нас пробел, или без него). В MS Excel это можно настраивать. Еще пример: Буква Ё по алфавиту после Е, но не по коду символа. Культурная среда — привычки восприятия, более точный термин — региональные (страна как регион) стандарты. Следовательно, эти операторы выполняют сравнение строк без учета регистра и настроек культурной среды.

Методы класса String

Ниже перечислены некоторые наиболее интересные методы этого класса, сгруппированные по назначению:

1) Сравнение строк:
public static int Compare(string strA, string strB);
public static int Compare(string strA, string strB, bool ignoreCase);
Статический метод, сравнивает строку strA со строкой strB. Возвращает положительное значение, если строка strA больше строки strB; отрицательное значение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Если параметр ignoreCase принимает логическое значение true, то при сравнении не учитываются различия между прописным и строчным вариантами букв. В противном случае эти различия учитываются.

public static int Compare(string strA, int indexA, string strB, int indexB, int length);
Сравнивает части строк strA и strB. Сравнение начинается со строковых элементов strA[indexA] и strB[indexB] и включает количество символов, определяемых параметром length. Метод возвращает положительное значение, если часть строки strA больше части строки strB; отрицательное значение, если часть строки strA меньше части строки strB; и нуль, если сравниваемые части строк strA и strB равны.

public static int CompareOrdinal(string strA, int indexA, string strB, int indexB, int count);
Делает то же, что и метод Compare(), но без учета локальных установок.

public int CompareTo(object value)
Сравнивает вызывающую строку со строковым представлением объекта value. Возвращает положительное значение, если вызывающая строка больше строки value; отрицательное значение, если вызывающая строка меньше строки value; и нуль, если сравниваемые строки равны.

public static bool Equals(string a, string b, StringComparison comparisonType);
Возвращает логическое значение true, если строка a содержит ту же последовательность символов, что и строка b. Выполняется порядковое сравнение с учетом регистра, но без учета культурной среды. Параметр comparisonType определяет конкретный способ сравнения строк.

2) Конкатенация (соединение) строк Concat()
public static string Concat(string str0, string str1);
public static string Concat(params string[] values);
Комбинирует отдельные экземпляры строк в одну строку (конкатенация).

3) Поиск в строке
public bool Contains(string value)
Метод, который позволяет определить, содержится ли в строке определенная подстрока (value)

public bool StartsWith(string value)
Возвращает логическое значение true, если вызывающая строка начинается с подстроки value. В противном случае возвращается логическое значение false. public bool EndsWith(string value, StringComparison comparisonType)

Возвращает логическое значение true, если вызывающая строка оканчивается подстрокой value. В противном случае возвращает логическое значение false. Параметр comparisonType определяет конкретный способ поиска.

public int IndexOf(char value)
public int IndexOf(string value)
Находит первое вхождение заданной подстроки или символа в строке. Если искомый символ или подстрока не обнаружены, то возвращается значение -1.

public int IndexOf(char value, int startIndex)
public int IndexOf(string value, int startIndex)
public int IndexOf(char value, int startIndex, int count)
public int IndexOf(string value, int startIndex, int count)
Возвращает индекс первого вхождения символа или подстроки value в вызывающей строке. Поиск начинается с элемента, указываемого по индексу startIndex, и охватывает число элементов, определяемых параметром count (если указан). Метод возвращает значение -1, если искомый символ или подстрока не обнаружен.
LastIndexOf() . Перегруженные версии аналогичны методу IndexOf() То же, что IndexOf, но находит последнее вхождение символа или подстроки, а не первое.

Читайте также:  Найти токи методом наложения

public int IndexOfAny(char[] anyOf)
public int IndexOfAny(char[] anyOf, int startIndex)
public int IndexOfAny(char[] anyOf, int startIndex, int count)
Возвращает индекс первого вхождения любого символа из массива anyOf, обнаруженного в вызывающей строке. Поиск начинается с элемента, указываемого по индексу startIndex, и охватывает число элементов, определяемых параметром count (если они указаны). Метод возвращает значение -1, если не обнаружено совпадение ни с одним из символов из массива anyOf. Поиск осуществляется порядковым способом.

LastIndexOfAny. Перегруженные версии аналогичны методу IndexOfAny() Возвращает индекс последнего вхождения любого символа из массива anyOf, обнаруженного в вызывающей строке.

4) Разделение и соединение строк
public string[] Split(params char[] separator)
public string[] Split(params char[] separator, int count)
Метод, возвращающий массив string с присутствующими в данном экземпляре подстроками внутри, которые отделяются друг от друга элементами из указанного массива char или string.
В первой форме метода Split() вызывающая строка разделяется на составные части. В итоге возвращается массив, содержащий подстроки, полученные из вызывающей строки. Символы, ограничивающие эти подстроки, передаются в массиве separator. Если массив separator пуст или ссылается на пустую строку, то в качестве разделителя подстрок используется пробел. А во второй форме данного метода возвращается количество подстрок, определяемых параметром count.

public string[] Split(params char[] separator, StringSplitOptions options)
public string[] Split(string[] separator, StringSplitOptions options)
public string[] Split(params char[] separator, int count, StringSplitOptions options)
public string[] Split(string[] separator, int count, StringSplitOptions options)
В двух первых формах метода Split() вызывающая строка разделяется на части и возвращается массив, содержащий подстроки, полученные из вызывающей строки. Символы, разделяющие эти подстроки, передаются в массиве separator. Если массив separator пуст, то в качестве разделителя используется пробел. А в третьей и четвертой формах данного метода возвращается количество строк, ограничиваемое параметром count.
Но во всех формах параметр options обозначает конкретный способ обработки пустых строк, которые образуются в том случае, если два разделителя оказываются рядом. В перечислении StringSplitOptions определяются только два значения: None и RemoveEmptyEntries. Если параметр options принимает значение None, то пустые строки включаются в конечный результат разделения исходной строки. А если параметр options принимает значение RemoveEmptyEntries, то пустые строки исключаются из конечного результата разделения исходной строки.

public static string Join(string separator, string[] value, int startIndex, int count)
Строит новую строку, комбинируя содержимое массива строк. В первой форме метода Join() возвращается строка, состоящая из сцепляемых подстрок, передаваемых в массиве value. Во второй форме также возвращается строка, состоящая из подстрок, передаваемых в массиве value, но они сцепляются в определенном количестве count, начиная с элемента массива value[startIndex]. В обеих формах каждая последующая строка отделяется от предыдущей разделительной строкой, определяемой параметром separator.

5) Заполнение и обрезка строк
Trim() public string Trim()
public string Trim(params char[] trimChars)
Метод, который позволяет удалять все вхождения определенного набора символов с начала и конца текущей строки.
В первой форме метода Trim() из вызывающей строки удаляются начальные и конечные пробелы. А во второй форме этого метода удаляются начальные и конечные вхождения в вызывающей строке символов из массива trimChars. В обеих формах возвращается получающаяся в итоге строка.

public string PadLeft(int totalWidth)
public string PadLeft(int totalWidth, char paddingChar)
Позволяет дополнить строку символами слева. В первой форме метода PadLeft() вводятся пробелы с левой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth. А во второй форме данного метода символы, обозначаемые параметром paddingChar, вводятся с левой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth. В обеих формах возвращается получающаяся в итоге строка. Если значение параметра totalWidth меньше длины вызывающей строки, то возвращается копия неизмененной вызывающей строки.

PadRight() Аналогично PadLeft() Позволяет дополнить строку символами справа.

6) Вставка, удаление и замена строк
public string Insert(int startIndex, string value)
Используется для вставки одной строки в другую, где value обозначает строку, вставляемую в вызывающую строку по индексу startIndex. Метод возвращает получившуюся в итоге строку.

public string Remove(int startIndex, int count)
Используется для удаления части строки. В первой форме метода Remove() удаление выполняется, начиная с места, указываемого по индексу startIndex, и продолжается до конца строки. А во второй форме данного метода из строки удаляется количество символов, определяемое параметром count, начиная с места, указываемого по индексу startIndex.

public string Replace(string oldValue, string newValue)
Используется для замены части строки. В первой форме метода Replace() все вхождения символа oldChar в вызывающей строке заменяются символом newChar. А во второй форме данного метода все вхождения строки oldValue в вызывающей строке заменяются строкой newValue.

Смена регистра. ToUpper() public string ToUpper() Делает заглавными все буквы в вызывающей строке. ToLower() public string ToLower() Делает строчными все буквы в вызывающей строке.

7) Получение подстроки из строки
public string Substring(int startIndex)
public string Substring(int startIndex, int length)
В первой форме метода Substring() подстрока извлекается, начиная с места, обозначаемого параметром startIndex, и до конца вызывающей строки. А во второй форме данного метода извлекается подстрока, состоящая из количества символов, определяемых параметром length, начиная с места, обозначаемого параметром startIndex.

Пример следующей программы использует несколько из вышеуказанных методов:

Используйте при обработке текста все возможности, заложенные в класс String.

В C# широко используется такой тип данных (определяемый пользователем) как перечисление.

И наконец, следует рассмотреть важнейшее ключевое понятие как методы класса.

Ссылка на основную публикацию
Кёрхер 5500 с аквафильтром
Пылесос Karcher DS 5500 стал первым в мире серийным изделием, оснащенным жидкостным фильтром для удаления загрязнения из воздуха. Конструкция дополнена...
Какое сопротивление должно быть у кабеля
Приступая к измерению сопротивления изоляции кабеля важно учесть температурные показатели окружающей среды. Почему так? Это связано с тем, что при...
Какое стекло лучше наклеить на смартфон
Дисплей любого смартфона нуждается в постоянной защите, даже если вы приобрели самую последнюю модель. Не стоит пренебрегать возможностью установить дополнительное...
Кварцевый обогреватель расход энергии
Рассматривая варианты электрического отопления дома, квартиры или дачи, вы наверняка встречали такую разновидность бытовых приборов, как кварцевые обогреватели и пытались...
Adblock detector