Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Чтение данных из файла содержащего комментарии 
V
    Опции темы
htzg
Дата 17.4.2010, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



Здравствуйте!
Есть файл содержащий слова.
Так же в этом файле есть комментарии идущие после "--"

пример:

word1 word2 word3 -- comment
--comment
--------------------
word4 word5--comment

Пытаюсь создать функцию которая мне выдавала бы эти слова по-одному, т.е:
void GetWordFromFile(std::ifstream File, std::string WordFromFile, std::string RemarkSymbol)

В итоге все мои старания свелись к следующему:
Код:

Код

#include <string>
#include <sstream>
#include <fstream>
#include <iostream>

void GetWordFromFile(std::ifstream ifile, std::string Temp, std::string RemSymbol)
{
    std::string Line;
    static std::istringstream istrLine;
    bool stop=0;
    istrLine >> Temp;
    if(istrLine.eof())
        if(ifile.is_open())
            while(!stop && !ifile.eof())
            {
                //
                getline(ifile, Line);
                int RemPos = Line.find(RemSymbol);
                if(RemPos > -1)
                    Line = Line.substr(0,RemPos);
                istrLine.str(Line);
                istrLine >> Temp;
                //
                if(!istrLine.eof())
                    stop=1;
            }
}

// проверяю что получается...
int _tmain(int argc, _TCHAR* argv[])
{
    std::ifstream ifile;
    ifile.open("txt.txt");
    std::string temp;
    std::string RemSymbol("--");
    if(!ifile.fail())
    while(!ifile.eof())
        {
            GetGrdeclString(ifile, temp, RemSymbol);
            std::cout << temp << std::endl;
        }
    system("pouse");
    return 0;
}

Компилятор выдает одну ошибку : 
1>c:\program files\microsoft visual studio 8\vc\include\fstream(675) : error C2248: 'std::basic_ios<_Elem,_Traits>::bas ic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> c:\program files\microsoft visual studio 8\vc\include\ios(151) : see declaration of 'std::basic_ios<_Elem,_Traits>::bas ic_ios'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> This diagnostic occurred in the compiler generated function 'std::basic_ifstream<_Elem,_Traits> ::basic_ifstream(const std::basic_ifstream<_Elem,_Traits> &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]

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

П.с.: программированию (не считая школьный и университетский-ознакомительный курсы) учился сам, по самоучителю. Если в есть какие то принципиальные ошибки и/или недочеты, большая просьба - указать мне на них.
Спасибо!
PM MAIL   Вверх
toxx
Дата 17.4.2010, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 2
Всего: 13



Код

void GetWordFromFile(std::ifstream &ifile, std::string Temp, std::string RemSymbol)

PM MAIL   Вверх
htzg
Дата 17.4.2010, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



Спасибо большое!
Заработало! Только этот код похоже бесполезен! smile
А вообще на данную тему есть наработки? 
PM MAIL   Вверх
toxx
Дата 17.4.2010, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 2
Всего: 13



Не знаю, мб и есть...
Да и задачу сделать просто довольно...я бы так сделал:
Код

#include <string>
#include <fstream>
#include <iostream>
using namespace std;
void GetWordFromFile()
{
    ifstream ifile("txt.txt");
    string RemSymbol("--"),Line;
    while(getline(ifile, Line))
        if(Line.find(RemSymbol)) 
            cout<<Line.substr(0,Line.find(RemSymbol))<<endl;
    ifile.close();
}
int main()
{
    GetWordFromFile();
    return 0;
}


Это сообщение отредактировал(а) toxx - 18.4.2010, 00:44
PM MAIL   Вверх
htzg
Дата 19.4.2010, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



на самом деле, toxx, вышеизложенный код при прочтении файла типа:

word1 word2 word3 -- comment
--comment
--------------------
word4 word5--comment

выдаст следующее:

word1 word2 word3


word4 word5


1) не выдает слова по отдельности
2) выдает пустые строки

Вообще что в идеале нужно: перегрузить оператор >> (извлечение из потока) класса ifstream так что бы он при прочтение 
Код

int main()
{
ifstream ifile;
ifile.open("txt.txt");
string word;
while(!ifile.eof())
{
ifile >> word;
cout << word << endl;
}
return 0;
}


файла(см. выше), получить следующее:
word1
word2
word3
word4
word5




Это сообщение отредактировал(а) htzg - 19.4.2010, 21:40
PM MAIL   Вверх
toxx
Дата 19.4.2010, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 2
Всего: 13



htzg
Странно но у меня выдаёт вот так
Код

word1 word2 word3
word4 word5

без пробелов.
но задание понял всеравно не так =)

Это сообщение отредактировал(а) toxx - 19.4.2010, 23:26
PM MAIL   Вверх
toxx
Дата 19.4.2010, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 2
Всего: 13



Код

#include <string>
#include <fstream>
#include <iostream>
using namespace std;
void GetWordFromFile()
{
    ifstream ifile("txt.txt");
    string RemSymbol("--"),Line;
    int RemPos=1;
    while(getline(ifile, Line))
    {
        RemPos=Line.find(RemSymbol);
        Line.erase (RemPos,Line.size());
        while(RemPos!=-1&&Line.size()!=0)
        {
            RemPos = Line.find(" ");
            cout<<Line.substr(0,RemPos)<<endl;
            Line.erase (0,RemPos+1);
        }
        RemPos=-1;
    }
    ifile.close();
}
int main()
{
    GetWordFromFile();
    return 0;
}


Тогда так.

Это сообщение отредактировал(а) toxx - 19.4.2010, 23:43
PM MAIL   Вверх
htzg
Дата 30.4.2010, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



...Нужна (была) функция, при вызове которой из потока-файла извлекается слово(одно) в формате std::string, c учетом того что файл содержит комментарии идущие после "--" и до конца строки. При этом об оптимизации забывать нельзя т.к. файл содержит миллионы (до ~миллиарда) слов...
Кроме того между словами, перед ними и после них могут стоять пробелы и табы в неограниченном количестве. Могут быть строки которые ни чего не содержат.
Длина строки заранее не известна.
(По-простому говоря этот файл создается автоматически, но местами правится ручками)

Вот что у меня получилось:

Код

#include <string>
#include <sstream>
#include <queue>
#include <fstream>

#include "trim.cpp"  // содержит функцию trim о которой ниже...

using namespace std;

bool getsr(ifstream &ifile , string &s , string RemSymbol) 
//  ifile - файл-поток;
//  s - std::string в который запишется "слово из файла";
//  RemSymbol - (Remark Symbol) - символ обозначающий начало комментария (например: "--")
{
    static queue<string> qs;
    if(qs.size() != 0)
    {
        s = qs.front();
        qs.pop();
        return 1 ;
    }
    else
    {
        do
        {
            string str;
            getline(ifile, str);
            int rs = str.find(RemSymbol);
            if(rs > -1)
                str = str.substr(0,rs);
            char *ch = new char[ str.size() ];
            strcpy(ch, str.c_str());
            for(int i=str.size()-1 ; i > -1 ; i--)  // это replace :)
                if(ch[i] == '\t')
                    ch[i] = ' ' ;
            trim(ch); // эту функцию я благополучно скопировал:
                      // http://forum.vingrad.ru/articles/topic-157803/hl/trim/index.html
                      // спасибо автору!
            if(ch[0] != '\0' )
            {
                istringstream istr(ch);
                while(!istr.eof())
                {
                    istr >> str;
                    qs.push(str);
                }
            }
            delete [] ch;
        }
        while(!ifile.eof() && qs.size() == 0);
        if(ifile.eof() && qs.size() == 0)
            return 0 ;
        s = qs.front();
        qs.pop();
        return 1 ;
    }
}


Хочу пояснить почему функция bool, а не void: функция, по-мимо того что извлекает std::string, еще возвращает значение true или false. Значение false говорит о том что файл дочитан до конца(а считывается он строками) и все "слова" (из этой строки) извлечены.

Есть предложения по оптимизации(в принципе скорость пока устраивает)  ?
smile

Это сообщение отредактировал(а) htzg - 30.4.2010, 19:09
PM MAIL   Вверх
htzg
Дата 1.5.2010, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



немного переделал...

Код

#include <string>
#include <sstream>
#include <queue>
#include <fstream>
#include <iostream>

using namespace std;

void trimr(string &s)
{
    int i = s.size();
    if(i > 0)
    {
        for( string::iterator iter = s.end()-1 ; iter != s.begin() && (*iter == '\t' || *iter == ' ' ) ; iter--)
            i--;
        s = s.substr(0,i);
        if(s == "\t" || s == " ")
            s.clear();
    }
}

bool getsr(ifstream &ifile , string &s , string RemSymbol)
{
    static queue<string> qs ;
    if(qs.size() != 0)
    {
        s = qs.front();
        qs.pop();
        return 1 ;
    }
    else
    {
        do
        {
            string str;
            getline(ifile, str);
            int rs = str.find(RemSymbol);
            if(rs > -1)
                str = str.substr(0,rs);
            trimr(str);
            if(str.size() != 0 )
            {
                istringstream istr(str.c_str());
                while(!istr.eof())
                {
                    istr >> str;
                    qs.push(str);
                }
            }
        }
        while(!ifile.eof() && qs.size() == 0);
        if(ifile.eof() && qs.size() == 0)
            return 0 ;
        s = qs.front();
        qs.pop();
        return 1 ;
    }
}


вопрос все тот же :
Оптимизировать можно ?
PM MAIL   Вверх
htzg
Дата 1.5.2010, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



и еще не много....

Код

#include <string>
#include <sstream>
#include <queue>
#include <fstream>

using namespace std;

bool trimr(string &s)
{
    int i = s.size();
    if(i > 0)
    {
        for( string::iterator iter = s.end()-1 ; iter != s.begin() && (*iter == '\t' || *iter == ' ' ) ; iter--)
            i--;
        s = s.substr(0,i);
        if(s == "\t" || s == " ")
        {
            s.clear();
            return 0 ;
        }
        else
            return 1 ;
    }
    else
        return 0 ;
}
bool getsr(ifstream &ifile , string &s , string RemSymbol)
{
    static queue<string> qs ;
    if(qs.size() != 0)
    {
        s = qs.front();
        qs.pop();
        return 1 ;
    }
    else
    {
        do
        {
            string str;
            getline(ifile, str);
            int rs = str.find(RemSymbol);
            if(rs > -1)
                str = str.substr(0,rs);
            if(trimr(str) )
            {
                istringstream istr(str.c_str());
                while(!istr.eof())
                {
                    istr >> str;
                    qs.push(str);
                }
            }
        }
        while(!ifile.eof() && qs.size() == 0);
        if(ifile.eof() && qs.size() == 0)
            return 0 ;
        s = qs.front();
        qs.pop();
        return 1 ;
    }
}


пример использования:
Код

#include <vector>
#include <iostream>
int main()
{
    ifstream ifile;
    ifile.open("txt.txt");
    string s;
    if(!ifile.fail())
        while( getsr(ifile, s, "--") && s != "/")
            cout << s << endl;
    char ch;
    cin >> ch;
    return 0;
}

файл содержит:
word1 word2 -- comm
    -------------------
    word3--comm
/
word4


на экран выведется:
word1
word2
word3

Добавлено через 4 минуты и 3 секунды
Вопрос, по большому счету, решен.
Всем спасибо(toxx в особенности)!
Удачи!
 smile 

Это сообщение отредактировал(а) htzg - 1.5.2010, 15:34
PM MAIL   Вверх
toxx
Дата 1.5.2010, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 2
Всего: 13



htzg
Что-то вы долго отвечали... я уже и забыл про тему =)
А мой вариант падает да?=) ну просто интересно...как будет вести себя моя функция =)

Это сообщение отредактировал(а) toxx - 1.5.2010, 16:01
PM MAIL   Вверх
htzg
  Дата 1.5.2010, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 17.4.2010

Репутация: нет
Всего: нет



toxx
Ваша функция, при ее вызове, выдаст все слова сразу, скопом. А в остальном, вроде бы, нормально.  smile

Добавлено через 2 минуты и 5 секунд
Цитата(toxx @  1.5.2010,  16:01 Найти цитируемый пост)
Что-то вы долго отвечали... я уже и забыл про тему =)

Не до этого было... smile

PM MAIL   Вверх
toxx
Дата 1.5.2010, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 2
Всего: 13



htzg
хорошо, что работает как-то- это радует =)

А в оптимизации я вам ничем помочь не могу, т.к. с итераторами знаком поверхностно и не разу не применял( без STL обхожусь пока).

Добавлено через 2 минуты и 59 секунд
Странно что никто не заходит кроме меня отписаться, люди тут есть очень даже знающие думаю помоглибы..
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0842 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.