С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
#1

Посмотреть код - C++

01.08.2012, 20:14. Просмотров 1409. Ответов 20
Метки нет (Все метки)

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

Задача программы в следующем.
/*
* Программа принимает у пользователя путь к файлу.
* Разбирает файл по строкам и словам.
* Пользователь может ввести любое слово и получить данные в виде номеров строк в которых встречается данное слово.
* При желании вывести эти строки или искать другое слово
*/
так вот, прочитав тему по этому проекту честно ничего не понял, т.к. там пишется все сразу и за всем сложно уследить с самого начала. И я решил написать его собственными силами.
С классами я еще знаком слабо(через 1 главу только начнется их изучение) , только то что рассказывалось в общем.

Прошу у кого есть время и желание посмотрите код и скажите может есть что-то, что реализовано "ужасно", только не надо показывать как это можно реализовать более сложными способами, то что я использовал это, то что я прошел по книге.

Заранее благодарен за указание на все мои косяки
PS: Первый раз писал программу содержащую больше 100 строк

файл main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
* Программа принимает у пользователя путь к файлу. Разбирает файл по строкам и словам.
* Пользователь может ввести любое слово и получить данные в виде номеров строк в которых
* встречается данное слово.
* При желании вывести эти строки.
*/
 
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include "TextQuery.h"
 
int main() 
{
    //открытие файла
    std::string file_name_str;
    std::ifstream file_f;
    std::cout << "Enter file name and its type(name.type)" << std::endl
            << " -> ";
    std::cin >> file_name_str;
    open_file(file_f, file_name_str);
 
    Quer tq;
    tq.add_line_to_vec(file_f);     // каждую строку в вектор
    //закрытие файла(больше не понадобится)
    file_f.close();
 
    //заполняем карту
    tq.line_to_word_in_map();
    
    // Для искомого слова
    std::string word_for_search;
    //Ввод слова и вывод результатов
    found_and_result(tq, word_for_search);
    std::cout << std::endl;
 
    //Меню
    menu();         
    
    //проверка ответов
    int otv;            //Для принятия ответа
    do {
        std::cin >> otv;
        if (otv == 1) { 
            output_lines(tq, word_for_search);
            std::cout << std::endl;
            menu();
        }
        if (otv == 2) {
            found_and_result(tq, word_for_search);
            std::cout << std::endl;
            menu();
        }
    }while (otv != 0);
 
    return 0;
}

файл TextQuery.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
 
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <string>
 
class Quer {
public:
    typedef std::vector<std::string>::size_type siz_vec;     // тип хранящий размер вектора
    typedef std::map<std::string, std::set<int> >::iterator map_iter;           // вывод данных по найденому слову
 
    // МЕТОДЫ
    void add_line_to_vec(std::ifstream&);                   // Заполнение вектора строками из файла
    void line_to_word_in_map();                             // Разбор строк и заполнение карты
    void get_vec(std::vector<std::string>&);                // Получение вектора
    void print_map(std::map<std::string, std::set<int> > &); // получение карты
    std::map<std::string, std::set<int> >::iterator get_iter_word_map(std::string);  // Получене итератора найденого слова в карте
    void print_result(std::string, bool&);
    
 
private:
    std::map<std::string, std::set<int> > word_map;     // карта хранящая слово(ключ) и номера строк в которых оно встречается(набор)
    std::vector<std::string> line_text;                 // вектор хранящий каждую строку текста
};
 
void open_file(std::ifstream&, std::string);            // открытие файла
void not_punct (std::string&);                          // удаление знаков пунктуации и приведение к строчному виду
void found_and_result(Quer&, std::string&);             // Ввод слова для поиска и вывод результата
void menu();                                            // меню
void output_lines(Quer&, std::string&);                 // Вывод строк с найденым словом
 
#endif

файл TextQuery.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include "TextQuery.h"
 
//Открываем файл
void open_file(std::ifstream& f, std::string ss)
{ 
    if (std::ifstream(ss.c_str()) == NULL) {
        system("cls");
        std::cout << "Error file not found!" << std::endl
            << "Enter file name and its type(name.type)" << std::endl
            << " -> ";
        std::string if_error;
        std::cin >> if_error;
        open_file(f, if_error);
    } else {
        f.open(ss.c_str());
        system("cls");
        std::cout << "Excellent! The file \'"<< ss
            << "\' is opened!" << std::endl;
    }
}
 
//Заполняем вектор строками из открытого файла
void Quer::add_line_to_vec (std::ifstream &f) 
{
    std::string line;
    while (std::getline(f, line)) {
        line_text.push_back(line);
    }       
}
 
//Удаление знаков пунктуации и перевод к строчному виду выбраного слова
void not_punct(std::string &pun)
{
    
    for(std::string::size_type i(0); i != pun.length(); i++) {
        if (isupper(pun[i]))
            pun[i] = tolower(pun[i]);
        if (ispunct(pun[i])) {
            pun.erase(i,1);
            --i;
        }
    }
}
 
//Разбираем строки по словам и заполняем карту
void Quer::line_to_word_in_map()
{
    Quer::siz_vec count(1);
    for(std::vector<std::string>::iterator iter=line_text.begin();
                                            iter != line_text.end(); iter++, count++) {
            std::istringstream stream(*iter);
            std::string word;
            while (stream >> word) {
                not_punct(word);
                word_map[word].insert(count);
            }
 
    }
}
 
//Получение данных вектора
void Quer::get_vec(std::vector<std::string>& ver)
{
    for(std::vector<std::string>::iterator iter = line_text.begin();
                                            iter != line_text.end(); iter++) {
        ver.push_back(*iter);
    }
}
 
//Получение карты
void Quer::print_map(std::map<std::string, std::set<int> > &mape)
{
    for(std::map<std::string, std::set<int> >::iterator iter = word_map.begin();
                                                        iter != word_map.end(); iter++) {
            mape.insert(std::make_pair(iter->first,iter->second));
    }
}
 
//Поиск слова в карте
std::map<std::string, std::set<int> >::iterator Quer::get_iter_word_map(std::string word_founds)
{
    not_punct(word_founds);
    return word_map.find(word_founds);
}
 
//Вывод результата
void Quer::print_result(std::string word_found, bool &fail) 
{
    map_iter iter = Quer::get_iter_word_map(word_found);
    if (iter != word_map.end()) {
        system("cls");
        std::cout << "The word \'" << word_found << "\' found in the following lines:";
        for (std::set<int>::iterator iter_set = iter->second.begin(); iter_set != iter->second.end(); iter_set++) {
            std::cout << " " << *iter_set;
        }
        std::cout << "." << std::endl;
        fail = false;
    } else {
        std::cout << std::endl << "Word not fount!" << std::endl;
        fail = true;
    }
}
 
// Ввод слова для поиска и вывод результата
void found_and_result(Quer& tq, std::string& search)
{
    bool fail = false;      //Проверка на правильность ввода
    do {
        if (fail) 
            std::cout << "Please try again." <<std::endl << "-> ";
        else 
            std::cout << "What word search?" << std::endl << "-> ";
        std::cin >> search;
 
        //Вывод результата
        tq.print_result(search, fail);
    }while (fail);
}
 
 
// меню
void menu()
{
    std::cout << "To show themselves prompt, type 1" << std::endl
        << "To find another word enter 2" << std::endl
        << "To exit, type 0" << std::endl << "-> " << std::flush;
}
 
//Вывод строк со встречающимся словом
void output_lines(Quer& que, std::string &word_for_search) 
{
    std::cout << "The output lines: " << std::endl;
    std::vector<std::string> vec_str_out;
    que.get_vec(vec_str_out);
    Quer::map_iter iter = que.get_iter_word_map(word_for_search);
    for(std::set<int>::iterator it_set = iter->second.begin(); it_set != iter->second.end(); it_set++) {
        std::cout << "(line " << *it_set << ") " << vec_str_out[*it_set-1] << std::endl;
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2012, 20:14
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Посмотреть код (C++):

Посмотреть код встроенных математических функций. Открыть cmath - C++
Каким образом можно посмотреть, как в c++ считаются встроенные функции в библиотеке cmath(math.h) ? Например, хочу посмотреть, как...

Односвязный список (псевдокод) - поменять два элемента местами (посмотреть, правильно ли написан код) - C++
Дан односвязный список 0...9 Дан указатель на первый элемент - p Поменять местами 5 и 6 node *a =...

можеш посмотреть - C++
вообще не понимаю

Посмотреть содержимое папки - C++
Здравствуйте, хочу написать прожку, которая будет показывать содержимое папки, а так же может переходить из папки в папку. Вот этот код...

Посмотреть элементы массива - C++
Подскажите, как посмотреть элементы динамического массива при дебаге (VS 2010)?

Где посмотреть простейший парсер на C++? - C++
Надо отпарсить и подсветить несколько строк (для начала - хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками,...

20
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
02.08.2012, 22:28  [ТС] #16
Цитата Сообщение от alex_x_x Посмотреть сообщение
чем лучше size_t count = 1;
пока тип не посмотришь (с не самым очевидным сокращением) непонятно что это (скаляр, объект, итп)
я не так понял просто

Добавлено через 6 часов 4 минуты
подскажите, как сделать, чтобы он спрашивал снова при вводе букв или это невозможно ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//проверка ответов (меню)
    do {
        int otv(4);
        std::cin >> otv;
        switch (otv) {
            case 1:
                output_lines(tq, word_for_search);
                std::cout << std::endl;
                menu();
                break;
            case 2:
                goto Search_any_word;               
                break;
            case 3:
                system("cls");
                goto Select_another_file;
                break;
            case 0:
                return 0;
            default:    
                std::cout << "-> ";
                break;
        }
    }while (true);
Добавлено через 24 минуты
при вводе букв он зацикливается и все
скажите хотя бы можно так вообще сделать или нет?
0
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
02.08.2012, 23:45 #17
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main () {
    int i;
    while (!(std::cin >> i)) {
        std::cout << "bad" << std::endl;
        std::cin.clear(); 
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    }
    std::cout << "result - " << i << std::endl;
}
хотя я не очень силен в извращениях с вводом
1
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
02.08.2012, 23:50  [ТС] #18
спасибо, ща посмотрю
0
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
05.08.2012, 15:40  [ТС] #19
вот, что-то исправил, что-то переписал. Прошу взглянуть еще раз.

main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Программа принимает у пользователя путь к файлу.  
* Разбирает файл по строкам и словам.
* Пользователь может ввести любое слово и получить данные в виде номеров строк в которых встречается данное слово.
* При желании вывести эти строки, начать поиск другого слова или выбрать другой файл.
*/
 
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include "TextQuery.h"
 
void text_menu();                               // меню
bool open_file(std::ifstream&, std::string);    // открытие файла
 
int main() 
{
    //открытие файла
    std::string file_name_str;
    std::ifstream file_with_text;
 
Select_another_file:    
    std::cout << "Enter file name and its type(name.type), enter to exit closep" << std::endl
            << " -> ";
    bool open = true;
    do {
        if (!open) {
            system("cls");
        std::cout << "Error file not found!" << std::endl
            << "Enter file name and its type(name.type), enter to exit closep" << std::endl
            << " -> ";
        }
        open = false;
        std::cin >> file_name_str;
        if (file_name_str == "closep")
            return 0;
    }while (!open_file(file_with_text, file_name_str));
 
 
    Quer tq;
    tq.lines_from_file_add_to_vector(file_with_text);       // каждую строку в вектор
    //закрытие файла(больше не понадобится)
    file_with_text.close();
 
    //заполняем карту
    tq.line_to_word_in_map();
    
    // Для искомого слова
    std::string word_for_search;
    bool fail = false;          // Результат поиска файла
 
Search_any_word:
    //Ввод слова и вывод результатов
    do {
        fail ? std::cout << "Please try again." <<std::endl << "-> " :
            std::cout << "What word search?" << std::endl << "-> ";
        std::cin >> word_for_search;
        tq.print_result(word_for_search, fail);
    }while(fail);
    std::cout << std::endl;
 
    //Меню
    text_menu();            
    
    //проверка ответов (меню)
    do {
        int otv;
        std::cin >> otv;
        switch (otv) {
            case 1:
                tq.output_lines(word_for_search);
                std::cout << std::endl;
                text_menu();
                break;
            case 2:
                goto Search_any_word;               
                break;
            case 3:
                system("cls");
                goto Select_another_file;
                break;
            case 0:
                return 0;
            default:    
                std::cout << "-> ";
                break;
        }
    }while (true);
 
    return 0;
}
 
////////////////////////////////////////////////////////////////////////
 
// меню
void text_menu()
{
    std::cout << "To show themselves prompt, type 1" << std::endl
        << "To find another word enter 2" << std::endl
        << "To select another file, type 3" << std::endl
        << "To exit, type 0" << std::endl << "-> " << std::flush;
}
 
//Открываем файл
bool open_file(std::ifstream& f, std::string name_file)
{ 
    f.close();
    f.clear();
    f.open(name_file.c_str());
    return f.is_open();
}
TextQuery.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
 
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
 
class Quer {
public:
    typedef std::map<std::string, std::set<int> >::const_iterator map_const_iter;   // Вывод данных по найденому слову
    typedef std::vector<std::string> vector_str;                                    // Вектор строк
    typedef std::vector<std::string>::const_iterator vector_str_const_iter;         // Константный итератор на вектор строк
 
    // МЕТОДЫ
    void lines_from_file_add_to_vector(std::ifstream&);         // Заполнение вектора строками из файла
    void line_to_word_in_map();                                 // Разбор строк и заполнение карты
    vector_str get_vector() const;                              // Получение вектора
    std::map<std::string, std::set<int> > get_map() const;      // Получение карты
    map_const_iter get_iter_word_map(std::string);              // Получение итератора найденого слова в карте
    void print_result(std::string, bool&);                      // Вывод результата
    void output_lines(std::string);                             // Вывод строк с найденым словом
    
 
private:
    std::map<std::string, std::set<int> > word_map;     // Карта хранящая слово(ключ) и номера строк в которых оно встречается(набор)
    std::vector<std::string> line_text;                 // Вектор хранящий каждую строку текста
};
 
void not_punct (std::string&);                  // Удаление знаков пунктуации и приведение к строчному виду
 
#endif
TextQuery.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include "TextQuery.h"
 
//Заполняем вектор строками из открытого файла
void Quer::lines_from_file_add_to_vector(std::ifstream &f) 
{
    std::string line;
    while (std::getline(f, line)) {
        line_text.push_back(line);
    }       
}
 
//Удаление знаков пунктуации и перевод к строчному виду выбраного слова
void not_punct(std::string &pun)
{
    pun.erase(std::remove_if(pun.begin(),pun.end(),ispunct), pun.end()); //Удаление знаков пунктуации
    for(std::string::size_type i(0); i != pun.length(); i++) {           // Перевод слова к строчному виду
        if (isupper(pun[i]))
            pun[i] = tolower(pun[i]);
    }
}
 
//Разбираем строки по словам и заполняем карту
void Quer::line_to_word_in_map()
{
    std::size_t count(1);       //нормера строк для пользователя
    for(std::vector<std::string>::const_iterator iter=line_text.begin();
                                            iter != line_text.end(); iter++, count++) {
            std::istringstream stream(*iter);
            std::string word;
            while (stream >> word) {
                not_punct(word);
                word_map[word].insert(count);
            }
 
    }
}
 
//Получение данных вектора
Quer::vector_str Quer::get_vector() const
{
    Quer::vector_str ver;
    std::copy (line_text.begin(), line_text.end(), std::back_inserter(ver));
    return ver;
}
 
//Получение карты
std::map<std::string, std::set<int> > Quer::get_map() const
{
    std::map<std::string, std::set<int> > mape;
    for(std::map<std::string, std::set<int> >::const_iterator iter = word_map.begin();
                                                        iter != word_map.end(); iter++) {
            mape.insert(std::make_pair(iter->first,iter->second));
    }
    return mape;
}
 
//Поиск слова в карте
Quer::map_const_iter Quer::get_iter_word_map(std::string word_founds)
{
    not_punct(word_founds);
    return word_map.find(word_founds);
}
 
//Вывод результата
void Quer::print_result(std::string word_found, bool &fail) 
{
    map_const_iter iter = Quer::get_iter_word_map(word_found);
    if (iter != word_map.end()) {
        system("cls");
        std::cout << "The word \'" << word_found << "\' found in the following lines:";
        for (std::set<int>::const_iterator iter_set = iter->second.begin(); iter_set != iter->second.end(); iter_set++) {
            std::cout << " " << *iter_set;
        }
        std::cout << "." << std::endl;
        fail = false;
    } else {
        std::cout << std::endl << "Word not fount!" << std::endl;
        fail = true;
    }
}
 
//Вывод строк со встречающимся словом
void Quer::output_lines(std::string word_for_search)
{
    std::cout << "The output lines: " << std::endl;
    Quer::map_const_iter iter = Quer::get_iter_word_map(word_for_search);
    for(std::set<int>::const_iterator iter_set = iter->second.begin(); iter_set != iter->second.end(); iter_set++) {
        std::cout << "(line " << *iter_set << ") " << line_text[*iter_set-1] << std::endl;
    }
}
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
05.08.2012, 15:48 #20
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Получение данных вектора
Quer::vector_str Quer::get_vector() const
{
    Quer::vector_str ver;
    std::copy (line_text.begin(), line_text.end(), std::back_inserter(ver));
    return ver;
}
 
//Получение карты
std::map<std::string, std::set<int> > Quer::get_map() const
{
    std::map<std::string, std::set<int> > mape;
    for(std::map<std::string, std::set<int> >::const_iterator iter = word_map.begin();
                                                        iter != word_map.end(); iter++) {
            mape.insert(std::make_pair(iter->first,iter->second));
    }
    return mape;
}
Зачем? Ведь можно просто вернуть те объекты которые в классе, т.е.

C++
1
2
3
4
5
6
7
8
9
Quer::vector_str Quer::get_vector() const
{
   return line_text;
}
//Получение карты
std::map<std::string, std::set<int> > Quer::get_map() const
{
   return word_map;
}
1
DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 524
Записей в блоге: 1
05.08.2012, 16:08  [ТС] #21
ForEveR, я об этом как-то не задумывался, что так можно, спасибо
0
05.08.2012, 16:08
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.08.2012, 16:08
Привет! Вот еще темы с ответами:

Посмотреть символ в битовой схеме - C++
есть запись например такая: unsigned char bits=1; как ее можно посмотреть в битовой схеме, т.е. чтобы вывод на экран выглядел так:...

Подскажите, где посмотреть информацию - C++
Всем добрый день! Скачал недавно САПР для создания выкроек и там есть возможность создания адаптивных выкроек. Все это дело пишется на...

Как посмотреть содержимое заголовочных файлов в Си? - C++
доброго. как посмотреть содержимое заголовочных файлов в си я про #include &lt;intrin.h&gt; те которые включены в проект их видно, а как...

Подскажите где можно посмотреть исходники - C++
Подскажите где можно посмотреть исходники законченых программ на С++, активно использующих ООП: инкапсуляцию, наследование и полиморфизм?...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
21
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.