Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
01.08.2012, 20:14     Посмотреть код #1
Приветствую всех
Вот решил написать программу сам, чтобы так скажем закрепить все полученные на сегодняшний день знания по С++ (еще не полностью дочитал книгу Липпмана)
Вот как раз в этой книге надо было сделать проект.

Задача программы в следующем.
/*
* Программа принимает у пользователя путь к файлу.
* Разбирает файл по строкам и словам.
* Пользователь может ввести любое слово и получить данные в виде номеров строк в которых встречается данное слово.
* При желании вывести эти строки или искать другое слово
*/
так вот, прочитав тему по этому проекту честно ничего не понял, т.к. там пишется все сразу и за всем сложно уследить с самого начала. И я решил написать его собственными силами.
С классами я еще знаком слабо(через 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;
    }
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
HomeR_J_SimpsoN
59 / 59 / 2
Регистрация: 15.10.2010
Сообщений: 356
01.08.2012, 20:36     Посмотреть код #2
Очень неплохой код.
Единственное что, лучше прописать
C++
1
using namespace std;
там где Вы часто используете это пространство имен. Так повышается читабельность кода.
И кусок
C++
1
2
3
4
5
6
7
8
9
10
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();
        }
лучше заменить switch'ем, тк там проще добавить новое условие, в нем сразу однозначно выбирается ветка следования и опять же немного увеличивается читабельность.

Так держать!
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
01.08.2012, 20:41  [ТС]     Посмотреть код #3
Цитата Сообщение от HomeR_J_SimpsoN Посмотреть сообщение
Очень неплохой код.
Единственное что, лучше прописать
C++
1
using namespace std;
там где Вы часто используете это пространство имен. Так повышается читабельность кода.
И кусок
C++
1
2
3
4
5
6
7
8
9
10
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();
        }
лучше заменить switch'ем, тк там проще добавить новое условие, в нем сразу однозначно выбирается ветка следования и опять же немного увеличивается читабельность.

Так держать!
Спасибо, а про switch я чет забыл, сейчас изменю

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
do {
        std::cin >> otv;
        switch (otv) {
            case 1:
                output_lines(tq, word_for_search);
                std::cout << std::endl;
                menu();
                break;
            case 2:
                found_and_result(tq, word_for_search);
                std::cout << std::endl;
                menu();
                break;
            case 0:
                return 0;
        }
    }while (true);
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
02.08.2012, 01:47     Посмотреть код #4
1. я бы рекомендовал заменить not_punct на следующую строчку:
C++
1
s.erase(std::remove_if(s.begin(), s.end(), std::ispunct), s.end());
думаю и работать будет побыстрее, нежели много ерейзов.

2. придирка, но функциям типа manu, print_result и тд не место в заголовочном файле, вы же класс пишете

3.
// Ввод слова для поиска и вывод результата
void found_and_result
как я по названию функции должен понять, что ожидается ввод??

кроме того: ИМХО [практически] любой ввод/вывод в функциях/методах это безвкусица и не надо так делать. к примеру в open_file можно возвратить код ошибки или типа того...
std::cout << "Excellent! The file \'"<< ss
<< "\' is opened!" << std::endl;
чушня....

.
пс: рекурсия там тоже лишняя.

да и вообще зачем делать открытие файла - методом........



Цитата Сообщение от DaskOFF Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
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;
* * }
}
тут сразу несколько. во 1-х искал где у вас в функции изменяется word_for_search, так и не нашел. сбиваете с толку ссылкой...
во 2-х я так понимаю по т.н. iter можно изменить содержимое map-а?
ну и в 3-х не понравилось, что получаете из класса аж целый вектор строк. только для того чтобы использовать его как текст, тоесть ваш класс можно также использовать как удалитель знаков препинания... странно...

а вот, то что использовал set это хорошо.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
02.08.2012, 02:07     Посмотреть код #5
Цитата Сообщение от DaskOFF Посмотреть сообщение
C++
1
2
3
private:
* * std::map<std::string, std::set<int> > word_map; * * // карта хранящая слово(ключ) и номера строк в которых оно встречается(набор)
* * std::vector<std::string> line_text; * * * * * * * * // вектор хранящий каждую строку текста
имхо - дублирование данных
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
02.08.2012, 02:22  [ТС]     Посмотреть код #6
Цитата Сообщение от OstapBender Посмотреть сообщение
1. я бы рекомендовал заменить not_punct на следующую строчку:
C++
1
s.erase(std::remove_if(s.begin(), s.end(), std::ispunct), s.end());
думаю и работать будет побыстрее, нежели много ерейзов.
я не знаю такую функцию, но завтра гляну обязательно, и не думаю что будет много удалений даже если и будут знаки препинания максимум 3 это "!!!", текст пишется по всем правилам.

Цитата Сообщение от OstapBender Посмотреть сообщение
2. придирка, но функциям типа manu, print_result и тд не место в заголовочном файле, вы же класс пишете
ну я не знаю насколько это плохо, но мне проще посмотреть в заголовочном файле какие у меня есть функции и какие аргументы им передаются

Цитата Сообщение от OstapBender Посмотреть сообщение
3.
// Ввод слова для поиска и вывод результата
void found_and_result
как я по названию функции должен понять, что ожидается ввод??
для этого написан комментарий

Цитата Сообщение от OstapBender Посмотреть сообщение
кроме того: ИМХО [практически] любой ввод/вывод в функциях/методах это безвкусица и не надо так делать. к примеру в open_file можно возвратить код ошибки или типа того...
поподробней, если можно

Цитата Сообщение от OstapBender Посмотреть сообщение
чушня....

пс: рекурсия там тоже лишняя.

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


Цитата Сообщение от OstapBender Посмотреть сообщение
тут сразу несколько. во 1-х искал где у вас в функции изменяется word_for_search, так и не нашел. сбиваете с толку ссылкой...
во 2-х я так понимаю по т.н. iter можно изменить содержимое map-а?
ну и в 3-х не понравилось, что получаете из класса аж целый вектор строк. только для того чтобы использовать его как текст, тоесть ваш класс можно также использовать как удалитель знаков препинания... странно...
спасибо за ответ, завтра посмотрю, пока понял итераторы сделать константными

Цитата Сообщение от OstapBender Посмотреть сообщение
а вот, то что использовал set это хорошо.


Цитата Сообщение от Jupiter Посмотреть сообщение
имхо - дублирование данных
можно поподробней, а то не понял


В любом случае, щас пойму какие ошибки допускаю через месяц будет проще в универе
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
02.08.2012, 02:44     Посмотреть код #7
Как по мне так дикий оверхед, но ладно, это учитывать не будем - замечания.

1) Название методов должно быть говорящим, если я вижу
C++
1
void add_line_to_vec(std::ifstream&);
я понимаю, что функция добавляет строку в вектор... Однако принимает она файл. Да и как оказывается еще и все строки из файла добавляет.
2)
C++
1
2
void get_vec(std::vector<std::string>&);                // Получение вектора
    void print_map(std::map<std::string, std::set<int> > &); // получение карты
Логичнее сделать
C++
1
2
std::vector<std::string> get_vec() const;
std::map<std::string, std::set<int> > get_map() const;
А может даже по ссылке или const-ссылке возвращать (по ссылке, если снаружи можно менять данные, по const-ссылке, если нельзя).

3)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Открываем файл
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;
    }
}
Бредовый метод несколько. Тут будет несколько замечаний.

3.1)
C++
1
(std::ifstream(ss.c_str()) == NULL)
NULL - это Си. В С++ нужно было юзать 0, а теперь в С++11 нужно юзать nullptr. Ну а конкретно в данном случае лучше использовать is_open.
3.2) Файл пытается открыться два раза (т.е. если условие ложно - файл уже открыт, а вы потом еще раз его открываете).
3.3) Рекурсия здесь абсолютно не к месту. Если юзер подал неверный файл - выкидываем эксепшн, т.к. это ошибка, а в программе, которая это использует уже делаем какую-нибудь обработку этого исключения.
4) not_punсt как уже сказали лучше использовать std::remove_if.
5) Вывод в методах на консоль, использование очистки консоли и т.д. - плохо.
6) Вообще не юзаются const-ссылки, не юзаются const-функции класса.

Вот как-то так, при беглом просмотре кода. А так молодец. Вперед.
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
02.08.2012, 02:58     Посмотреть код #8
Цитата Сообщение от DaskOFF Посмотреть сообщение
я не знаю такую функцию, но завтра гляну обязательно, и не думаю что будет много удалений даже если и будут знаки препинания максимум 3 это "!!!", текст пишется по всем правилам.
посмотри, посмотри.. полезная весчь. из <algorithm>.
да и выглядит лаконичней. и тут аж 2 функции. я так понимаю раз не сталкивался, то стоит расписать, чтоб вопросов сразу же не возникло.
типа remove_if в соответствии с предикатом (в нашем случае ispunct) , перемешивает контейнер, так что несоответствующие элементы оказываются в конце, и возвращает итератор на то место где они начинаются. от туда и до конца мы и рубим через ерейз.

Цитата Сообщение от DaskOFF Посмотреть сообщение
ну я не знаю насколько это плохо, но мне проще посмотреть в заголовочном файле какие у меня есть функции и какие аргументы им передаются
ну просто у тебя это уже вспомогательные функции, и они содержат ТЕКСТ, который возможно ты или кто-то другой захотят видеть другой... придется лезть в "исходники" и перекомпилировать.. не хорошо...
ну и вообще 1 файл - 1 сущность. (за исключением сборников сущностей типа windows.h)

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

Цитата Сообщение от DaskOFF Посмотреть сообщение
поподробней, если можно
про ввод - выше.
ну а вывод... тоже нафиг не сдался внутри. ну про "чушню". вот будет использовать какой нить чел твою библиотеку, к примеру Торвальдс, ну запустит че-то. и его реакция будет на ети ""Excellent! The file \'"<< ss << "\' is opened!" " будет типа http://img.by/i/kgFxs.jpg

про возврат значения ошибки:
к примеру как сделано в винде... во многих функциях...

помещаем ввесь код в неймспейс. и делаешь допустим (имя Неймспейса --> TextQuery)
enum { ERR_SUCCESS, ERR_FILE_NOT_EXIST, WRONG_KEY, FILE_EMPTY .... }
и делаешь
C++
1
2
3
4
5
6
long err;
if ((err = open_file(...)) != TextQuery::ERR_SUCCESS) {
switch(err) {
case TextQuery::ERR_FILE_NOT_EXIST: ...
}
}
ну это уже идиализированный вариант. и немного запутанный. можно вообще возвращать 0 или -1 там и тп...
и ВООБЩЕ открывать то файл лучше своими руками, а потом уже ОТКРЫТЫЙ передавать в функцию..

Цитата Сообщение от DaskOFF Посмотреть сообщение
по поводу заполнения стека, я не думаю что пользователь будет очень много раз ошибаться в выборе файла
если ошибаюсь поправьте
не в этом дело. просто рекурсию надо использовать там, - где это действительно удобно и необходимо. всякие задачи которые простыми методами решаются неэффективно.
тут: это удобно? - не знаю.
эффективно и логично? - нет.

Цитата Сообщение от DaskOFF Посмотреть сообщение
спасибо за ответ, завтра посмотрю, пока понял итераторы сделать константными
пожалуйста ) ну начни с етого...)
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
02.08.2012, 03:01  [ТС]     Посмотреть код #9
Цитата Сообщение от ForEveR Посмотреть сообщение

3.2) Файл пытается открыться два раза (т.е. если условие ложно - файл уже открыт, а вы потом еще раз его открываете).
5) Вывод в методах на консоль, использование очистки консоли и т.д. - плохо.
6) Вообще не юзаются const-ссылки, не юзаются const-функции класса.
это более менее понятно

Цитата Сообщение от ForEveR Посмотреть сообщение
NULL - это Си. В С++ нужно было юзать 0, а теперь в С++11 нужно юзать nullptr. Ну а конкретно в данном случае лучше использовать is_open.
4) not_punсt как уже сказали лучше использовать std::remove_if.
3.3) Рекурсия здесь абсолютно не к месту. Если юзер подал неверный файл - выкидываем эксепшн, т.к. это ошибка, а в программе, которая это использует уже делаем какую-нибудь обработку этого исключения.
с этим придется завтра разобраться, т.к. такие функции в книге не описываются, надо будет понять как их использовать

а так завтра возможно возникнут какие-нибудь вопросы.
кстати как узнать поддерживается ли с++11?

Классы изучу получше станет, думаю, просто все задачи в основном идут на 1 пройденную тему. На 1 тему задачи проще решать и проблем почти не возникает, это плохо, как по мне, вроде по отдельности все применить можешь, а когда все сразу уже сложнее
Хорошо хоть форум такой нашел, где если что помогут
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
02.08.2012, 03:31     Посмотреть код #10
Цитата Сообщение от ForEveR Посмотреть сообщение
NULL - это Си. В С++ нужно было юзать 0
с чего? в c++ NULL и так 0, зато не нужно гадать в вызове f(1, 2, 0, NULL, "hello"); где 0 это число, а где указатель

Добавлено через 17 минут
Цитата Сообщение от DaskOFF Посмотреть сообщение
open_file(file_f, file_name_str);
Цитата Сообщение от DaskOFF Посмотреть сообщение
void open_file(std::ifstream&, std::string);
а что, если в функцию передать уже открытый файл?
Цитата Сообщение от DaskOFF Посмотреть сообщение
std::ifstream(ss.c_str()) == NULL
шок-контент, так не бывает - что это за способ проверки открытия файла
Цитата Сообщение от DaskOFF Посмотреть сообщение
typedef std::vector<std::string>::size_type siz_vec;
плохое название.. и да, чем size_t не угодил, паранойя?
Цитата Сообщение от DaskOFF Посмотреть сообщение
Quer::siz_vec count(1);
если хочешь запутать турецкую разведку - пиши именно так

Цитата Сообщение от DaskOFF Посмотреть сообщение
for(std::vector<std::string>::iterator iter = line_text.begin(); iter != line_text.end(); iter++) { ver.push_back(*iter); }
C++
1
std::copy( line_text.begin(),  line_text.end(), std::back_inserter(ver));
и еще больше функторов
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
02.08.2012, 04:14     Посмотреть код #11
alex_x_x, Не настаиваю, но http://www.stroustrup.com/bs_faq2.html#null предпочитаю прислушиваться.
А проверка файла конечно странный способ, но раз есть operator void*() то вцелом корректный. Кстати http://cplusplus.com/reference/iostr...erator_voidpt/ вот откуда берутся плохие примеры.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
02.08.2012, 09:04     Посмотреть код #12
Цитата Сообщение от ForEveR Посмотреть сообщение
Не настаиваю, но http://www.stroustrup.com/bs_faq2.html#null предпочитаю прислушиваться.
In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0.
не слишком сильно настаивает


Цитата Сообщение от ForEveR Посмотреть сообщение
А проверка файла конечно странный способ, но раз есть operator void*() то вцелом корректный. Кстати http://cplusplus.com/reference/iostr...erator_voidpt/ вот откуда берутся плохие примеры.
странный способ проверить все же..
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
02.08.2012, 15:09  [ТС]     Посмотреть код #13
Цитата Сообщение от alex_x_x Посмотреть сообщение
если хочешь запутать турецкую разведку - пиши именно так
номера строк должны идти с 1, а строк может быть полный вектор

Добавлено через 3 минуты
Цитата Сообщение от ForEveR Посмотреть сообщение
вот откуда берутся плохие примеры.
а есть подобный сайт с хорошими примерами?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
02.08.2012, 15:16     Посмотреть код #14
DaskOFF, Стадарт языка.) Хотя там тоже попадается иногда не очень.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
02.08.2012, 15:27     Посмотреть код #15
Цитата Сообщение от DaskOFF Посмотреть сообщение
номера строк должны идти с 1, а строк может быть полный вектор
Цитата Сообщение от DaskOFF Посмотреть сообщение
Quer::siz_vec count(1);
чем лучше size_t count = 1;
пока тип не посмотришь (с не самым очевидным сокращением) непонятно что это (скаляр, объект, итп)
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 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 минуты
при вводе букв он зацикливается и все
скажите хотя бы можно так вообще сделать или нет?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
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;
}
хотя я не очень силен в извращениях с вводом
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 1
02.08.2012, 23:50  [ТС]     Посмотреть код #18
спасибо, ща посмотрю
DaskOFF
 Аватар для DaskOFF
112 / 112 / 9
Регистрация: 02.05.2012
Сообщений: 521
Записей в блоге: 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;
    }
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.08.2012, 15:48     Посмотреть код
Еще ссылки по теме:

C++ Посмотреть элементы массива
Односвязный список (псевдокод) - поменять два элемента местами (посмотреть, правильно ли написан код) C++
Посмотреть код встроенных математических функций. Открыть cmath C++

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

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 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;
}
Yandex
Объявления
05.08.2012, 15:48     Посмотреть код
Ответ Создать тему
Опции темы

Текущее время: 10:02. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru