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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> std::search и std::istream_iterator, Экспешн stream_iterator is not dereferen 
:(
    Опции темы
X-3R1
Дата 8.4.2009, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Вопрос почему появляется эксепшн в подобном случае:

Код

    std::ifstream cmdFile( path.c_str() );

    std::istream_iterator<std::string> it(cmdFile);
    std::istream_iterator<std::string> end;

    std::vector<std::string> block;
    block.push_back( "part " );
        block.push_back( "modify" );
        block.push_back( "rigid_body" );
        block.push_back( "name_and_position" );

        std::search( it, end, block.begin(), bock.end() );          // вылетает эксешпн istream_iterator is not dereferencable


Протрассировал std:: search, эксепшн в функции:

Код

template<class _FwdIt1,
    class _FwdIt2,
    class _Diff1,
    class _Diff2> inline
    _FwdIt1 _Search(_FwdIt1 _First1, _FwdIt1 _Last1,
        _FwdIt2 _First2, _FwdIt2 _Last2, _Diff1 *, _Diff2 *)
    {    // find first [_First2, _Last2) match
    _DEBUG_RANGE(_First1, _Last1);
    _DEBUG_RANGE(_First2, _Last2);
    _Diff1 _Count1 = 0;
    _Distance(_First1, _Last1, _Count1);
    _Diff2 _Count2 = 0;
    _Distance(_First2, _Last2, _Count2);

    for (; _Count2 <= _Count1; ++_First1, --_Count1)                      // эксепшн на второй итерации
        {    // room for match, try it
        _FwdIt1 _Mid1 = _First1;
        for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1, ++_Mid2)
            if (_Mid2 == _Last2)
                return (_First1);
            else if (!(*_Mid1 == *_Mid2))                                       // а точнее тут при *_Mid1
                break;
        }
    return (_Last1);
    }


Эксепшн, на второй итерации основного цикла, почему-то при ++_First1, _First1 (входной итератор) становится невалидным. Ошибка при разыменовывании _Mid1.

Другие алгоритмы, типа std::find работают smile

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


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



X-3R1, сливай из файла сначало в контейнер из файла в тот же вектор (через std::copy), а затем уже в этом векторе ищи значения из blok. Тебе нужен еще итератор для определения - нашел ли что или нет std:smile

Добавлено через 49 секунд
гы. смайл заменил 
Цитата

smile


Добавлено через 1 минуту и 34 секунды
фак.
Код

std::search

PM MAIL   Вверх
X-3R1
Дата 8.4.2009, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Угу это как вариант, но так бы не хотелось временную память создавать (
PM MAIL   Вверх
Lazin
Дата 8.4.2009, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



это не exception а assert
скорее всего дело в чтении файла, видимо после прочтения первой строки, читать становится нечего...
PM MAIL Skype GTalk   Вверх
mrbrooks
Дата 8.4.2009, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



Цитата(X-3R1 @  8.4.2009,  11:19 Найти цитируемый пост)
Угу это как вариант, но так бы не хотелось временную память создавать ( 

дело в том что бы найти значение нужен итератор типа
Код

std::istream_iterator<std::string>::iterator it;

К этому итератору результат из 
Код

std::search( it, end, block.begin(), bock.end() );

не присвоить.

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

std::ifstream cmdFile( path.c_str() );
if (cmdFile)
{
//твой код
}

 возможно файл либо не открывается, либо его нет. 
PM MAIL   Вверх
X-3R1
Дата 8.4.2009, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Не, данные из файла прочитались нормально, std::find же работает. Такая же фигня, когда пытаюсь данные из файла загнать вначале в std::stringstream smile а потом уже работать с его входными итераторами.

Добавлено через 6 минут и 16 секунд
Цитата(mrbrooks @  8.4.2009,  09:25 Найти цитируемый пост)
дело в том что бы найти значение нужен итератор типа
    
std::istream_iterator<std::string>::iterator it;

К этому итератору результат из 

std:smile( it, end, block.begin(), bock.end() );

не присвоить.

Не совсем так, для работы этого алгоритма пойдут любые итераторы, поиск же производится через разыменовывание и operator ==():

Код

 else if (!(*_Mid1 == *_Mid2))  
                break;



Цитата(mrbrooks @  8.4.2009,  09:25 Найти цитируемый пост)
да забыл сказать - у меня все нормально компилится с твоим кодом. я бы на твоем месте сделал проверку

Да, проверка есть:
Код

    std::ifstream cmdFile( path.c_str() );

    if (!cmdFile)
    {
        SysLog::error( (std::string("Can't open the cmd file: ") + path).c_str() );
        return;
    }

PM MAIL   Вверх
mrbrooks
Дата 8.4.2009, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



Цитата(X-3R1 @  8.4.2009,  11:28 Найти цитируемый пост)
Не совсем так, для работы этого алгоритма пойдут любые итераторы, поиск же производится через разыменовывание и operator ==():

у меня не подошли любые итераторы.
PM MAIL   Вверх
Lazin
Дата 8.4.2009, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(mrbrooks @  8.4.2009,  12:09 Найти цитируемый пост)
у меня не подошли любые итераторы

это как?

данный код ищет в файле последовательность строк:
Цитата
part 
modify
rigid_body
name_and_position
причем первая строка должна-быть обязательно с пробелом на конце

Это сообщение отредактировал(а) Lazin - 8.4.2009, 12:27
PM MAIL Skype GTalk   Вверх
mrbrooks
Дата 8.4.2009, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



Lazin, 
за этот код студия мне вломила в печень
Код

std::istream_iterator<std::string>::iterator it;
it = std::search( it, end, block.begin(), bock.end());


хотя возможно - я что то не учел.
PM MAIL   Вверх
X-3R1
Дата 8.4.2009, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(mrbrooks @  8.4.2009,  10:33 Найти цитируемый пост)
за этот код студия мне вломила в печень


угу, потому что вместо
Код

std::istream_iterator<std::string>::iterator it;

надо
Код

std::istream_iterator<std::string> it;



Цитата(Lazin @  8.4.2009,  10:27 Найти цитируемый пост)
причем первая строка должна-быть обязательно с пробелом на конце

Нет в первой строке лишний пробел вкрался случайно smile
PM MAIL   Вверх
mrbrooks
Дата 8.4.2009, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



X-3R1, здесь опечатка произошла - копировал твой код и ничерта не исправил.  smile
По этому будет так:
Код

std::vector<std::string>::iterator v;
v = std::search( it, end, block.begin(), bock.end());


Добавлено через 52 секунды
Собственно за это и получил в печень.
PM MAIL   Вверх
Lazin
Дата 8.4.2009, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(mrbrooks @  8.4.2009,  12:43 Найти цитируемый пост)
Собственно за это и получил в печень

алгоритм возвращает std::istream_iterator<std::string>

Добавлено через 2 минуты и 13 секунд
попробовал это запустить у себя, получаю ту-же ошибку, хотя по идее все должно работать... smile 
PM MAIL Skype GTalk   Вверх
mrbrooks
Дата 8.4.2009, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



Цитата(Lazin @  8.4.2009,  12:56 Найти цитируемый пост)
алгоритм возвращает std::istream_iterator<std::string>

я и это попробывал. 2008 студия шлет меня так же подальше. 

потому я говорил о промежуточном контейнере. 
PM MAIL   Вверх
Lazin
Дата 8.4.2009, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(mrbrooks @  8.4.2009,  13:05 Найти цитируемый пост)
потому я говорил о промежуточном контейнере

тогда придется читать весь файл в память, для чего тогда вообще использовать итератор?
странно то, что файл можно прочитать через итератор it, но внутри алгоритма файл читаться перестает
выглядит это примерно так:
в std:smile создается копия итератора it, при первом проходе все работает, так-как при создании временной копии итератора реальное чтение из файла не происходит
далее выполняется оператор ++ для копии итератора, который вызывает оператор >> т.е пытается прочитать след. значение из файла, и происходит ошибка, с mingw этот код работатет

Добавлено через 45 секунд
вместо std:smile следует подставить std :: search smile 
PM MAIL Skype GTalk   Вверх
mrbrooks
Дата 8.4.2009, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



Цитата(Lazin @  8.4.2009,  13:15 Найти цитируемый пост)
тогда придется читать весь файл в память, для чего тогда вообще использовать итератор?

а как же тогда я узнаю результат без итератора?

к примеру как здесь

Добавлено через 1 минуту и 20 секунд
Цитата(Lazin @  8.4.2009,  13:15 Найти цитируемый пост)
вместо std:smile следует подставить std :: search smile  

рожа смайла скрыла твою идею
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.0584 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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