как я могу прочитать ровно 128 байтов из fstream в строковый объект? [дубликат]

Как мне прочитать ровно 128 байтов из fstream в строковый объект?

Я написал код, чтобы прочитать первые 128 байтов файла и распечатать их, а затем последние 128 байтов файла и распечатать их. Последняя часть работает, поскольку вы можете легко выполнить итерацию до EOF, но как мне получить ровно 128 байт спереди? Приведенный ниже код не работает, поскольку вы не можете добавить 128 к итератору ifstream, он не индексируется, а только увеличивается (кажется).

Конечно, я мог бы сделать итератор и * ++ 128 раз, но должен быть простой способ сделать это в одну строку, верно?

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

int main(int argc, char **argv)
{
    std::ifstream ifs ("input.txt",std::ifstream::in | std::ifstream::binary);

    if (ifs.good())
    {
    // read first 128 bytes into a string
        ifs.seekg(0,std::ifstream::beg);
        std::string first128((std::istreambuf_iterator<char>(ifs)),
                             (std::istreambuf_iterator<char>(ifs))+128);

        std::cout << first128 << std::endl;

    // read last 128 bytes into a string
        ifs.seekg(-128,std::ifstream::end);
        std::string last128((std::istreambuf_iterator<char>(ifs)),
                            std::istreambuf_iterator<char>());

        std::cout << last128 << std::endl;

        return 0;
    }

    return 1;
}
8
задан Southern Hospitality 22 August 2010 в 04:39
поделиться

2 ответа

char buffer[129];
ifs.read (buffer,128);
buffer[128] = '\0';
first128 = buffer;

Как насчет этого:

template <typename Itr, typename Out>
void copy_n(Itr it, size_t count, Out out)
{
    for(size_t i=0;i<count;++i)
      out = *it++;
} 

...

std::string first128; 
std::istreambuf_iterator<char> it(ifs);
copy_n( it, 128,
  std::back_inserter<std::string>(first128) );
1
ответ дан 6 December 2019 в 01:38
поделиться

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

std::vector<char> buffer(128); // create a buffer
ifs.read( &buffer[0], buffer.size() ); // read to buffer
std::string first128( buffer.begin(), buffer.end() ); // copy from vector

Мне кажется, что с реализацией iostreams они перестарались. Попытка использовать итераторы для потокового ввода-вывода слишком сложна.

Кстати, я подозреваю, что реализация, которую вы пытались выполнить, под прикрытием будет выполнять различные промежуточные буферизации (возможно, часть в ядре, часть в библиотеке), а также перераспределение и копирование строки несколько раз. раз по мере роста.

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

1
ответ дан 6 December 2019 в 01:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: