LINUX.ORG.RU

std::copy_n не перемещает итератор на следующий символ за последним скопированным.

 


0

2

Собственно код:

#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;

int main(){
    string src("01234567890123456789");

    string dst1;
    dst1.reserve(6);

    string dst2;
    dst2.reserve(6);

    istringstream is(src);

    copy_n( std::istreambuf_iterator<char>( is ), 6, std::back_inserter( dst1 ) );
    cout << dst1 << endl;

    copy_n( std::istreambuf_iterator<char>( is ), 6, std::back_inserter( dst2 ) );
    cout << dst2 << endl;
}

Вывод:

$ g++ t.cpp && ./a.out 
012345
567890

Хотя по идее должно быть:

012345
678901

Или я чего-то не понимаю?

ЗЫ:

$ g++ -v
Используются внутренние спецификации.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/9.3.0/lto-wrapper
Целевая архитектура: x86_64-pc-linux-gnu
Параметры конфигурации: /var/calculate/tmp/portage/sys-devel/gcc-9.3.0-r1/work/gcc-9.3.0/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/9.3.0 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/9.3.0 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/9.3.0/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/9.3.0/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/include/g++-v9 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/9.3.0/python --enable-languages=c,c++,objc,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 9.3.0-r1 p3' --disable-esp --enable-libstdcxx-time --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-fixed-point --enable-targets=all --enable-libgomp --disable-libmudflap --disable-libssp --disable-libada --disable-systemtap --enable-vtable-verify --enable-lto --with-isl --disable-isl-version-check --enable-default-pie --enable-default-ssp
Модель многопоточности: posix
gcc версия 9.3.0 (Gentoo 9.3.0-r1 p3) 
★★★★★

Последнее исправление: WatchCat (всего исправлений: 2)

Возвращает итератор (куда копирует) за последним скопированным. А сами исходные итераторы вообще не обязан изменять (почти что не должен).

anonymous
()
Ответ на: комментарий от fsb4000

Нда, и нахрена так делать?

Вот не могут в stl хоть что-то да не сделать через Ж.

Придётся возвращаться к тупому for

WatchCat ★★★★★
() автор топика
Последнее исправление: WatchCat (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Ты хочешь поговорить об этом?

anonymous
()
Ответ на: комментарий от WatchCat

Ты сперва объясни, зачем это извращение через istreambuf_iterator. Потом можно поговорить про «нахрена так делать?»

anonymous
()
Ответ на: комментарий от anonymous

Мне надо прочитать определённое количество char в строку из потока. Можно через тупой for с push_back. Но хотелось как-то покрасивше.

WatchCat ★★★★★
() автор топика
Ответ на: комментарий от WatchCat

Мне надо прочитать определённое количество char в строку из потока.

Нет. Ты хочешь не прочитать, а получить текущую позицию в потоке. Не подменяй понятия.

Ни один из алгоритмов copy (_if, _n) ничего не гарантирует на счет побочных эффектов итераторов-аргументов.

anonymous
()
Ответ на: комментарий от anonymous

Нет. Ты хочешь не прочитать, а получить текущую позицию в потоке.

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

WatchCat ★★★★★
() автор топика
Ответ на: комментарий от fsb4000

my bad. Спасибо. Да, что-то я самый явный итератор пропустил.

WatchCat ★★★★★
() автор топика
Последнее исправление: WatchCat (всего исправлений: 1)
Ответ на: комментарий от WatchCat

а зачем тут push_back?

int main(){
    string src("01234567890123456789");

    string dst1(6, '0'), dst2(6, '0');    
    istringstream is(src);

    for (auto& c: dst1) is >> c;
    cout << dst1 << endl;
    
    for (auto& c: dst2) is >> c;
    cout << dst2 << endl;
}

самое тупое решение - чаще всего самое правильное

Lrrr ★★★★★
()
Ответ на: комментарий от fsb4000

Что хотел показать: побочный эффект - позиция в потоке - зависит от фазы Луны?

anonymous
()
Ответ на: комментарий от fsb4000

Ан нет, всё не очень хорошо - istream_iterator пропускает пробелы.

Поставь вместо 3 пробел и увидишь 012456 вместо 012 45.

Короче либо тупой for, либо in.read в промежуточный буфер.

UPD. А, не, это дефолтное поведение istream. Так что всё норм, это отключаемо.

WatchCat ★★★★★
() автор топика
Последнее исправление: WatchCat (всего исправлений: 1)
Ответ на: комментарий от fsb4000

Ну может и for лучше в твоей задаче.

Но с пробелом тоже можно. Итераторы гибкие…

https://gcc.godbolt.org/z/bGT17o

Да в общем я уже решил, что ну эту всю новомодную хрень. Буду старым дедовским способом через промежуточный буфер vector<char>.

Хотя если бы string::data() возвращал не const char*, то было бы намного проще.

WatchCat ★★★★★
() автор топика
Ответ на: комментарий от WatchCat

Хотя если бы string::data() возвращал не const char*, то было бы намного проще.

Начиная с C++17 возвращает, а до этого можно делать &str[0].

xaizek ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.