Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
1

Подскажите как прогу допилить. Выборка цитат из текста.

03.12.2011, 21:31. Показов 1590. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет)
Вобщем нужно написать прогу, которая считывает текст из файла и выводит цитаты.

Прогу написал, все просто, все ок
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
#include "stdafx.h"
#include <clocale>
#include <fstream>
#include <iostream>
 
using namespace std;
 
char * get_quotes_from_file(ifstream &file);
 
int main()
{
    setlocale(LC_ALL, "russian");
 
    ifstream file;
    file.open("D:\\file.txt", ios::in);
 
    if(!file.is_open())
    {
        cout << "Ошибка при открытии файла." << endl;
        system("pause");
        return 0;
    }
    while(!file.eof())
        cout << get_quotes_from_file(file);
 
    system("pause");
    return 0;
}
 
char * get_quotes_from_file(ifstream &file)
{
    char *c = new char[],
        *quote = new char[500];
    bool flag = true;
    quote[0] = '\0';
    file >> c;
    if(c[0] == '"')
    {
        while(flag == true)
        {
            if(c[strlen(c) - 1] == '"') flag = false;
            strcat(quote, c);
            strcat(quote, " ");
            file >> c;
        }
        quote[strlen(quote)] = '\0';
    }
    return quote;
}
Но препод говорит так char *c = new char[], *quote = new char[500]; делать нельзя, нужно жестко указывать размер массива. Но при этом рассмотреть ситуацию, что будет, если мы выйдем за границы массива...
Скажите плиз как быть в такой ситуации?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.12.2011, 21:31
Ответы с готовыми решениями:

Подскажите как допилить regexp
Я хочу найти общее количество вхождений следующих символов (*, /, ^, +, -, cos, sin, tan) в...

допилить прогу для шифрования
есть прога для шифрования: cseg segment org 100h start: mov ah,1ah mov dx,offset dta int...

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

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

19
Заблокирован
Автор FAQ
03.12.2011, 22:10 2
Валентин^_^, что подразумевается под цитатой - текст в кавычках?Тогда это совсем по другому можно реализовать
0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
03.12.2011, 22:33  [ТС] 3
да, текст в кавычках

я знаю, что можно по другому, но нужно именно вот так
0
Заблокирован
Автор FAQ
03.12.2011, 22:48 4
Ниже реализация посредством std::string. К достойнствам кроме малого объёма кода можно также отнести отсутствие ограничений на длинну текста в файле и длинну цитат(благо в string можно динамически изменять не заботясь о памяти)
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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
int main()
{
    int bpos, lpos;
    string text, str;
    system("chcp 1251");
    ifstream ifs("file.txt");
    if(!ifs)
        cout<<"Error open file.txt\n";
    else
    {
        while(getline(ifs,str))
            text += str;
        ifs.close();
        cout<<"Text in file : \n"<<text<<endl;
        cout<<"Citates in text : \n";
        lpos = -1;
        while((bpos = text.find('"',lpos + 1)) != - 1)
        {
            if((lpos = text.find('"',bpos + 1)) != - 1)
                cout<<text.substr(bpos,lpos - bpos).c_str()<<endl;
            else
                break;
        }
    }
    system("pause");
    return 0;
}
Содержание file.txt
Thfghjg fghjgj jdg, gjj: "Rfggf, dgfgg!"...
Fgfdg fgf ffd : "dfdg fhgfh fdgf", - gjhgf fgj !"DSgfdg ghgh!" - fjgjhj.

Вывод цитат
Citates in text :
"Rfggf, dgfgg!"
"dfdg fhgfh fdgf"
"DSgfdg ghgh!"
Миниатюры
Подскажите как прогу допилить. Выборка цитат из текста.  
1
Заблокирован
Автор FAQ
03.12.2011, 22:55 5
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
но нужно именно вот так
- запрещено использовать string???
Ведь у меня та же что и в вашем алгоритме логика

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
while((bpos = text.find('"',lpos + 1)) != - 1)
- ищу открывающую кавычку
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
if((lpos = text.find('"',bpos + 1)) != - 1)
- и если нашёл закрывающую
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
cout<<text.substr(bpos,lpos - bpos).c_str()<<endl;
- вывожу подстроку с позиции открывающей до позиции закрывающей - как по мне проще ну ни как

Добавлено через 5 минут

Не по теме:

Валентин^_^, ау!Вам нужна от меня помощь???Хоть как то реагируйте на посты иначе уйду в лругой топик...

0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
03.12.2011, 22:57  [ТС] 6
спасибо конечно... но в лабе нельзя использовать сторонние классы...

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

сделал как-то вот так, но неверно)
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
#include "stdafx.h"
#include <clocale>
#include <fstream>
#include <iostream>
 
using namespace std;
 
char * get_quotes_from_file(ifstream &file);
 
int main()
{
    setlocale(LC_ALL, "russian");
 
    ifstream file;
    file.open("D:\\file.txt", ios::in);
 
    if(!file.is_open())
    {
        cout << "Ошибка при открытии файла." << endl;
        system("pause");
        return 0;
    }
    while(!file.eof())
        cout << get_quotes_from_file(file);
 
    system("pause");
    return 0;
}
 
char * get_quotes_from_file(ifstream &file)
{
    int q = 5;
    char *c = new char[q],
        *quote = new char[500];
    bool flag;
    quote[0] = '\0';
    
    file.getline(c, q);
    if(strlen(c) == q)
    {
        q += 10;
        char *tmp = new char[q];
        strcpy(tmp, c);
        delete [] c;
        c = tmp;
    }
 
    int i = 0;
    while(c[i] != '\0')
    {
        if(c[i] == '"')
        {
            int k = 0;
            for(int ind = i; ind < strlen(c); ind++, k++)
                quote[k] = c[ind];
            bool flag = true;
        
            while(flag == true)
            {
                file.getline(c, q);
 
                i = 0;
                while(c[i] != '\0')
                {
                    if(c[i] == '"')
                    {
                        k = strlen(c);
                        for(int ind = 0; ind < i; ind++, k++)
                            quote[k] = c[ind];
                        bool flag = false;
                        break;
                    }
                    i++;
                }
 
                strcat(quote, c);
            }
            quote[strlen(quote)] = '\0';
 
            break;
        }
        i++;
    }
 
    delete [] c;
    return quote;
}
вот как-то так нужно
0
Заблокирован
Автор FAQ
03.12.2011, 23:02 7
Валентин^_^, хорошо пределать под чаровские строки легко!Вам функции пользователя использовать хоть можно???Если да сейчас напишу аналоги string::find и всего делов. Также вопрос - считать всё содержимое в буфер запрещено или всё таки можно - тогда вообще как 2 пальца **** будет переделывать???

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от Валентин^_^ Посмотреть сообщение
file.getline(c, q);
- ну вот здесь у вас же облом будет, допустим цитатата 502 символа что вы делать будете???

0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
03.12.2011, 23:05  [ТС] 8
неа, работать с открытым потоком, не считывая файл в оперативку. Что за функции пользователя? Можно использовать ф-ии по работе со строками, да

Добавлено через 1 минуту
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- ну вот здесь у вас же облом будет, допустим цитатата 502 символа что вы делать будете???
а вот нужно обработать эту ситуацию! если так, то нужно создать новый массив большего размера, перезаписать его содержимым старого масива, удалить старый, указателю на старый массив присвоить новый..
0
Заблокирован
Автор FAQ
03.12.2011, 23:08 9
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
а вот нужно обработать эту ситуацию! если так, то нужно создать новый массив большего размера, перезаписать его содержимым старого масива, удалить старый, указателю на старый массив присвоить новый..
- хорошо рассматривается наиболее геморный вариант, нужно малость времени (сразу скажу все ваши функции выкину, будет читать цитататы и увеличивать память если мало символов, но сама реализация мне у вас не нравиться - это не в обиду)...
0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
03.12.2011, 23:12  [ТС] 10
Ну так я начинающий программер, только учусь) Если не сложно, напишите плиз)

Добавлено через 1 минуту
кстати еще одним из условий - должна быть функция отдельная, которая это делает, ну как у меня..
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
03.12.2011, 23:43 11
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
кстати еще одним из условий - должна быть функция отдельная, которая это делает, ну как у меня..
делает что? читает из файла? или находит цитаты? у вас одна функция делает и то и другое, что не есть гуд
0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
04.12.2011, 00:51  [ТС] 12
читает из файла и находит цитаты, да это в одной функции, ну так должно быть и обусловлено тем, что нужно работать с открытым потоком, не загружая файл в память

Добавлено через 1 час 2 минуты
хэээй!
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
04.12.2011, 00:53 13
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
хэээй!
все молчат потому что вы не слушаете советов
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
читает из файла и находит цитаты, да это в одной функции
разнесите чтение и поиск цитат по разным функциям, пусть тогда функция чтения из файла вызывает функцию которая ищет цитаты

Цитата Сообщение от Валентин^_^ Посмотреть сообщение
while(!file.eof())
к тому же такое чтение из файла не есть гуд, ошибка может произойти еще при считывании
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
file >> c;
и тогда этот цикл превратится в бесконечный
0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
04.12.2011, 00:56  [ТС] 14
Цитата Сообщение от Jupiter Посмотреть сообщение
пусть тогда функция чтения из файла вызывает функцию которая ищет цитаты
а смысл?
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
04.12.2011, 00:58 15
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
а смысл?
каждая функция должна делать свою подзадачу и ничего более, а чтения файла и и поиск цитат принципиально разные задачи
0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
04.12.2011, 01:01  [ТС] 16
это понятно, но изначально у меня проблема в том, как отловить тот момент, что массив (в который считывается из файла и тот массив, куда записываются цитаты) переполняется, и нужно увеличить размер массива
0
Заблокирован
Автор FAQ
04.12.2011, 11:38 17
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
а вот нужно обработать эту ситуацию! если так, то нужно создать новый массив большего размера, перезаписать его содержимым старого масива, удалить старый, указателю на старый массив присвоить новый..
- это можно осуществить в try{}catch(...){} блоке - принцип ниже
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
long bufsize = 8;
bool bOK = false;
char *str = NULL;
long pos = ifs.tellg();
while(!bOK)
{
    try
    {
        str= new char[bufsize];
        if(ifs.getline(str))//Если считывание ОК в catch не попадём
            bOK = true;//И условие окончания станет ДА
    }
    catch(...)
    {
        ifs.clear();//Нужно сбросить ошибки
        ifs.seekg(pos,ios::beg);//Отматываем обратно
        bufsize *= 2;
    }
}
Всё же я написал "человеческий" на мой взгляд вариант:
Текст считывается за 1 проход - оптимальней вряд ли с char-овским массивом вообще можно!
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
#include <iostream>
#include <fstream>
using namespace std;
 
long streamfind(ifstream &ifs, char smb, long pos)
{
    char ch;
    long lpos = -1;
    ifs.clear();
    ifs.seekg(pos,ios::beg);
    if(pos == ifs.tellg())
    {
        while(!ifs.eof() && lpos == -1)
        {
            ifs.get(ch);
            if(ch == smb)
                lpos = ifs.tellg();
        }
    }
    return lpos;
}
 
char * streamsubstr(char * str, ifstream &ifs, long pos, long len)
{
    ifs.seekg(pos,ios::beg);
    if(pos == ifs.tellg())
    {
        if(!(str = new char [len]))
            cout<<"Allocation memory error\n";
        else
            ifs.getline(str,len);
    }
    return str;
}
 
 
int main()
{
    int bpos, lpos;
    char * str;
    system("chcp 1251");
    ifstream ifs("file.txt");
    if(!ifs)
        cout<<"Error open file.txt\n";
    else
    {
        cout<<"Citates in text : \n";
        lpos = -1;
        while((bpos = streamfind(ifs,'"',lpos + 1)) != - 1)
        {
            if((lpos = streamfind(ifs,'"',bpos + 1)) != - 1)
            {
                if((str = streamsubstr(str,ifs,bpos,lpos - bpos)))
                {
                    cout<<str<<endl;
                    delete [] str;
                }
            }
            else
                break;
        }
        ifs.close();
    }
    system("pause");
    return 0;
}
PS:Я не стал писать алгоритм с try catch из принципа - это всё равно что находить 2*2 как корень кубичский из 64, сложность выше а эффективность таже - зачем сразу закладывать в алгоритм исключительные ситуации???Алгоритмы строят так, чтобы самой логикой построения не допускать исключений, а вы просите генерировать их - это не гуд!
Миниатюры
Подскажите как прогу допилить. Выборка цитат из текста.  
1
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
04.12.2011, 12:07  [ТС] 18
Спасибо большое) Буду разбираться в вашем коде!
0
Заблокирован
Автор FAQ
04.12.2011, 13:16 19
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
long streamfind(ifstream &ifs, char smb, long pos)
- функция осуществляет поиск символа smb в потоке ifs с позиции pos от начала. Если поиск успешен возвращаемое значение - lpos - позиция от начала первого найденного smb(учитуем что поиск был от позиции pos - это не означает что символ самый первый!). streamfind фактически аналог string::find только в качестве источника данных не строка а файловый поток

Добавлено через 2 минуты
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
char * streamsubstr(char * str, ifstream &ifs, long pos, long len)
- возвращает подстроку str из файлового потока ifs, с позиции pos длинной len. Если внутри функции были грабли - возвратом будет str == NULL. streamsubstr - аналог string:substr только в качестве источника данных не строка а файловый поток

Добавлено через 4 минуты
Цитата Сообщение от Валентин^_^ Посмотреть сообщение
Буду разбираться в вашем коде!
- надеюсь подсобил Вам. Если уж совсем жёсткие рамки то я уже добил вариант с логикой try_catch
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
long bufsize = 8;
bool bOK = false;
char *str = NULL;
long pos = ifs.tellg();
while(!bOK)
{
* * * * try
* * * * {
* * * * * * * * str= new char[bufsize];
* * * * * * * * if(ifs.getline(str))//Если считывание ОК в catch не попадём
* * * * * * * * * * * * bOK = true;//И условие окончания станет ДА
* * * * }
* * * * catch(...)
* * * * {
* * * * * * * * ifs.clear();//Нужно сбросить ошибки
* * * * * * * * ifs.seekg(pos,ios::beg);//Отматываем обратно
* * * * * * * * bufsize *= 2;
* * * * }
}
Так что пишите если ваш преподаватель не захочет воспринять вариант потокового пробора
0
25 / 25 / 11
Регистрация: 15.10.2009
Сообщений: 185
04.12.2011, 15:20  [ТС] 20
вечером буду делать отчет по лабе, и разбираться в коде. с трай кетч не вариант.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
надеюсь подсобил Вам
Да, очень)

Добавлено через 1 час 59 минут
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Так что пишите если ваш преподаватель не захочет воспринять вариант потокового пробора
В субботу пойду сдавать лабу, потом напишу комменты препода. Блин, каждую лабу ему сдавал как минимум с третьего раза. Эту - уже в четвертый раз будет)
0
04.12.2011, 15:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.12.2011, 15:20
Помогаю со студенческими работами здесь

Подскажите ,как отладить прогу
В матрице n*n поменять местами элементы симметрично побочной диагонали. пример: исходные данные :...

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

Подскажите план на прогу, как лучше написать и реализовать
Недавно посетила идея написать пока только для себя прогу с взаимодействием сайта. Собственно хочу...

Подскажите.Как сделать чтоб при много кликов на прогу выдовала ошибку
когда много кликаешь на программу и выдаёт ошибку ,эта программа уже запущена , как мне сделать?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru