itmo.ru aco.ifmo.ru c-visionlab.ru
вернуться в оглавление предыдущая глава предыдущий параграф следующий параграф следующая глава


2.3 Строковые переменные и константы

Стандартная библиотека языка С++ предоставляет программистам строковый тип данных (избавляет от использования массивов символов char[ ]).

Мы будем использовать тип данных string наряду со стандартными встроенными типами данных. И вы на первый взгляд не будете замечать никаких различий, хотя на самом деле это абстрактный тип данных, созданный на основе объектно-ориентированных возможностей языка С++. Надеюсь со временем вы тоже сможете создавать АТД, которыми можно будет пользоваться так же удобно и свободно, как и классом string.

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

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

#include <iostream>
#include <string>
using namespaсe std;

void main()
{
    string name="Vitaly"; // объявление, определение, инициализация
    string lastname="Domnenko";

    name+="M."+lastname; // конкатенация с присваиванием (накапливающее присваивание)
    cout<<"My name is "<<name<<endl; // вывод
}

Используя [ ] можно получить символ из любой позиции

char ch=name[5]; // символы нумеруются с нуля

Лексикографическое сравнение осуществляется с использованием операторов == < <= > >= !=. При лексикографическом сравнении последовательно сравниваются коды символов строки. Те символы считаются "больше", чьи коды "больше"и наоборот.

Кодировка (кодовая таблица) - это однозначное соответствие между целым число (кодом) и символом. При этом символ - это буква, цифра и другие графические знаки. Кодировки обычно составляют так, что символы следуют в алфавитном порядке и символ 'а' имеет наименьший код, а символ 'z' наибольший. Таким образом, выполняя лексикографическое сравнение можно разместить слова (строки) в алфавитном порядке. Это справедливо и для символов кириллического алфавита. Но не всегда, т.к. существует кодировки, в которой кириллические символы располагаются не в алфавитном порядке. Это кодировка КОИ8, которая обычно используется в операционных системах UNIX. Если вы пишете программу для UNIX, то нужно помнить, что простое лексикографическое сравнение не даст ожидаемого результата и нужно усложнять программу.

В нашем случае (при программировании для DOS или Windows) используются кодировки CP866 и СP1251 лексикографическое сравнение справедливо и дает нужный результат.

Ну и операторы для ввода/вывода строковых переменных >> << работают также как и для переменных других типов.

Функция Описание
Конструкторы
string() конструктор по умолчанию, создает пустую строку
string(const char* p) преобразующий конструктор
string(const string& str, size t pos=0, size t n=npos) копирующий конструктор (npos обычно равен -1 и указывает, что память не была выделена)
string(const char* p, size_t n) копирует n символов, р является базовым адресом
string(char c, size t n=l) создает строку из n символов с
Перегруженные операторы
string& operator= (const string& s) оператор присваивания
string& operator+= (const string& s) добавляет строку
char operator[] (size t pos) const возвращает символ из позиции pos
char& operator[] (size t pos) возвращает ссылку на символ из позиции pos
Функции-члены
string& append(const string& s, size_t pos=0, size t n=npos); Добавляет n символов начиная от позиции pos
string& assign(const string& s, size_t pos=0, size_t n=npos); строковому объекту присваивается n символов, начиная от позиции pos
string& insert(size_t posl, const string& str, size_t pos2=0 , size_t n=npos); вставляет n символов, полученных из str, начиная с позиции pos2, в строку с позиции posl
string& remove(size_t pos=0 , size_t n=npos); Удаляются n символов из строки начиная с позиции pos
string& replace(posl, nl, str, pos2=0, n2=npos); в неявной строке начиная с позиции posl заменяет nl символов n2 символами из подстроки str с позиции pos2
string& replace(pos, n, p, n2); заменяет n символов в позиции pos используя char* p из n2 символов или char* p до завершающего нуля, или повторяя символ с rep раз
char get_at (pos) const; возвращает символ из позиции pos
void put_at (pos, c); помещает символ с в позицию pos
size_t length() const; возвращает длину строки
const char* c_str() const; преобразует строку в традиционное char* представление
const char* data() const; возвращает базовый адрес строкового представления
void resize(n, c); void resize(n); изменяет строку, делая ее длину равной п; в первой функции в качестве заполняющего символа выступает с, а во второй - символ eos () (end-of-string, конец строки)
void reserve(size_t res_arg);size_t reserve() const; выделяет память под строку; первая функция переустанавливает this; вторая возвращает закрытый член res - размер выделенного фрагмента
size_t copy(p, n, pos=0) const; п симолов строки, начиная с позиции pos, копируются в char* p
string substr(pos=0, n=pos) const; возвращается подстрока из п символов строки
int compare(const string& str, size_t pos=0, size_t n=npos) const; сравнивает п символов строки, начиная с позиции pos, со строкой str. Возвращается ноль, если строки равны; в противном случае возвращается положительное или отрицательное целое значение, показывающее, что неявная строка лексикографически больше или меньше чем строка str.
size_t find (const string& str, size_t pos=0) const; в строке начиная с позиции pos производится поиск строки str. Если она найдена, возвращается позиция, в которой она начинается; в противном случае возвращается позиция npos
size_t rfind(str, pos=npos) const; похоже на find (), но при поиске первого совпадения строка сканируется в обратном направлении
size_t find_first_of(str, pos=0) const; производится поиск первого вхождения str начиная с позиции pos
size_t find_last_of(str, pos=npos) const; аналогично, но в обратном направлении
size_t find_first_not_of(str, pos=0) const; производится поиск первого символа, который не соответствует ни одному из символов str начиная с позиции pos
size_t find_last_not_of(str, pos=npos) const; аналогично, но в обратном направлении

Пример работы со строками

/////////////////////////////////////////////////////////////////////////////
// Программирование на языке высокого уровня. Основы языка С++
// Пример 2.1. Пример работы со сроками
// 
// http://aco.ifmo.ru/el_books/programming
// Университет ИТМО
/////////////////////////////////////////////////////////////////////////////
#include <iostream>   // подключение библиотеки ввода-вывода
#include <fstream>    // подключение библиотеки ввода-вывода в файл
#include <string>     // подключение описания string
using namespace std;  // подключение стандартного пространства имен для использования библиотек

/////////////////////////////////////////////////////////////////////////////
void main()
{
    ifstream ifile("test.html"); // создание потока ввода из файла по его имени
    string data; // строка куда будут записаны данные

    // цикл будет выполняться до тех пор, пока не встретиться конец файла
    while(!ifile.eof())
    {     
        string sLine;
        getline(ifile, sLine, '\n'); // читаем строку из файла до символа конца строки 
        data+=sLine;                 // записываем прочитанную строку в конец итоговой
    }

    size_t num_first=0; // номер символа, с которого будет происходить поиск
    // бесконечный цикл, выход из цикла - по оператору break
    while(true)
    {
        // находим номер символа, с которого начинается подстрока "<img ", начиная с символа под номером num_first
        // если такого текста не нашли - выход из цикла
        num_first=data.find("<img ", num_first);
        if(num_first==string::npos)
            break;
        // находим номер символа, с которого начинается подстрока ">", начиная с символа под номером num_first+1
        // если такого текста не нашли - выход из цикла
        size_t num_last=data.find(">", num_first+1);
        if(num_last==string::npos)
            break;

        // выделяем подстроку от "<" до ">"
        string image_data=data.substr(num_first+1, num_last-num_first-1);
        // запоминаем символ, начиная с которого будем искать в следующий раз
        num_first=num_last+1;

        // ищем номер символа, с которого начинается подстрока "src="" 
        // (для задания подстроки используем экранирующий символ)
        size_t num_first2=image_data.find("src=\"");
        // если такая подстрока была найдена
        if(num_first2!=string::npos)
        {
            // ищем закрывающую кавычку
            size_t num_last2=image_data.find("\"", num_first2+6);
            // если такая подстрока была найдена - выделяем в отдельную строку имя файла и выводим на экран
            if(num_last2!=string::npos)
            {
                string image_name=image_data.substr(num_first2+5, num_last2-num_first2-5);
                cout<<image_name<<endl;
            }
        }
    };
}
/////////////////////////////////////////////////////////////////////////////