Не могу понять, как использовать seekg Tellg для достижения следующего результата - PullRequest
0 голосов
/ 08 июля 2019

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

    #include <iostream>
    #include <sstream> 
    #include <vector>
    #include <iterator>
    #include <stdio.h>
    #include <string.h>    

    void create_index_info(ifstream& myFile, std::unordered_map<size_t, std::pair<std::streampos, size_t>>& map_index_start_end_pos)
    {
        size_t uiLength;
        size_t uiCount = 0;
        std::string line;

        while (getline(myFile, line))
        {        
            start_pos = myFile.tellg();
            uiLength = strlen(line.c_str());

            map_index_start_end_pos.emplace( uiCount, std::make_pair(start_pos, uiLength) );
            uiCount++;                        
        }
    }

    void print_index_info(ifstream& myFile, const std::unordered_map<size_t, std::pair<std::streampos, size_t>>& map_index_start_end_pos)
    {
        size_t uiLength;
        for(auto it = map_index_start_end_pos.begin(); it != map_index_start_end_pos.end(); it++)
        {
            auto res = it->second;

            myFile.clear();
            myFile.seekg(res.first, ios::beg);
            uiLength = res.second;

            char* buffer = (char*)malloc(uiLength * sizeof(char));
            myFile.read(buffer, uiLength);

            for(size_t uiCount = 0; uiCount < uiLength; uiCount++)
            {
                std::cout<< buffer[uiCount];
            }
            std::cout<<"\n";

            free(buffer);
            buffer = NULL;    
        }
    }

    int main()
    {
        std::unordered_map<size_t, std::pair<std::streampos, size_t>> map_index_start_end_pos;
        ifstream myFile("Filename.txt");
        create_index_info(myFile, map_index_start_end_pos);
        myFile.close();

        ifstream myFile1("Filename.txt");
        print_index_info(myFile1, map_index_start_end_pos);
        myFile1.close();
        return 0;
    }

Данные во входном текстовом файле содержат следующие записи:

9 10 11

8 7 5

67 34 12 45 9

20

Идеальный вывод для кода должен быть таким же, как ввод по модулю до упорядочения печатаемых строк (я использую неупорядоченную карту, поэтому вывод не нужно печатать в том же порядке, в котором он был подан). Однако мой код выводит какую-то фигню, в основном символы вида \ x00. Может кто-нибудь, пожалуйста, помогите мне выяснить, что не так в моем коде.

1 Ответ

0 голосов
/ 08 июля 2019
  • Ваша программа не компилируется.
  • Почему вы используете карту? Почему вектора недостаточно?
  • Почему getline, а не ignore? ignore быстрее и не выделяет память.

Вы, наверное, ищете это:

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

std::istream& get_line_idx( std::istream& is, std::vector<std::streampos>& result )
{
  for( std::streampos pos = is.tellg(); is.ignore( std::numeric_limits<std::streamsize>::max(), '\n' ); pos = is.tellg() )
    result.push_back( pos );
  return is;
}

void print( std::istream& is, std::vector<std::streampos>& pos )
{
  for( auto curpos : pos )
  {
    std::string line;
    is.seekg( curpos );
    std::getline( is, line );
    std::cout << line << std::endl;
  }
}

int main()
{
  std::vector<std::streampos> result;
  {
    std::ifstream is { "c:\\temp\\test.txt" };
    if( !is )
      return -1;
    get_line_idx( is, result );
  }

  {
    std::ifstream is { "c:\\temp\\test.txt" };
    if( !is )
      return -2;
    print( is, result );
  }

  return 0;
}
...