C++ Вопрос Чтение данных из файла через регулярное выражение

Начинающий
Статус
Оффлайн
Регистрация
12 Июл 2017
Сообщения
68
Реакции[?]
20
Поинты[?]
1K
К примеру есть код, который записывает игровые координаты игрока каждые две секунды в файл
C++:
{
std::ofstream File("n1ght.txt");
static std::string WriteLine;
if (isLocalPlayerMove(Forward_or_Backward) || isPlayerMove(Left_or_Right)) {
static ULONGLONG iTick = GetTickCount();
if (GetTickCount() - iTick > (ULONGLONG)2000) {
/* ":" - разделительный знак */
WriteLine += (std::to_string(GetLocalPlayerPosition().fX) + ":" + std::to_string(GetLocalPlayerPosition().fY) + "\n");
iTick = GetTickCount();
}
}
File.write(WriteLine.c_str(), WriteLine.length());
}
То что получилось в n1ght.txt
1542.32:1275.89
1437.43:1302.65
1436.84:1321:91

Вопрос. Как читать строки одной за другой после выполнения проверки на дистанцию.
Алгоритм бота должен быть такой:
Читаем первую строку из файла;
Находим из строки два числа;
Находим эти координаты в игровом мире;
Бежим до этих координат до тех пор пока дистанция между и игроком и точкой не станет меньше 1.5;
Читаем следующую строку;

C++:
std::cmatch result;
std::regex reg("(.*):(.*)");
float posX, posY;
//Файл откуда берутся координаты
std::ifstream fileread("n1ght.txt");
int i = 0;
for (std::string line; std::getline(fileread, line);) {

//Получаем две координаты в виде чисел из регекса и записываем их в result[1] и result[2]
std::regex_match(line.c_str(), result, reg);

//Переводим наши координаты из string в float для дальнейшей работы
posX = std::stof(result[1].str());   posY = std::stof(result[2].str());
float dist = Utils::Disatance(GetLocalPlayerPosition().fX, GetLocalPlayerPosition().fY, posX, posY);

//Если дистанция между игроком и точкой меньше 1.5 то мы должны перейти к следующей строке
if (dist <= 1.5f) {
line[i]++;
}
}
С этим кодом у меня читает только последнею строку, и дальше не работает.
 
Чел который заливает говно на GitHub
Начинающий
Статус
Оффлайн
Регистрация
2 Фев 2020
Сообщения
37
Реакции[?]
22
Поинты[?]
0
Вот тебе полноценный пример, работает заебись

C++:
// Example program
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <random>
#include <regex>
#include <streambuf>

#define Forward_or_Backward 1337
#define Left_or_Right 228

typedef uint64_t ULONGLONG;

bool isLocalPlayerMove(int move_type)
{
  std::random_device rd;
  std::default_random_engine gen(rd());
  std::uniform_int_distribution<int> dist(0, 1);
  return static_cast<bool>(dist(gen));
}

bool isPlayerMove(int move_type)
{
  std::random_device rd;
  std::default_random_engine gen(rd());
  std::uniform_int_distribution<int> dist(0, 1);
  return static_cast<bool>(dist(gen));
}

static uint64_t GetTickCount()
{
  struct timespec ts;
  clock_gettime(CLOCK_MONOTONIC, &ts);
  return (uint64_t)(ts.tv_nsec / 1000000) + ((uint64_t)ts.tv_sec * 1000ull);
}

struct glpp {
  float fX;
  float fY;
};

glpp GetLocalPlayerPosition()
{
  static bool first_time = true;
  static int minValX = -2048, minValY = -2048;
  static int maxValX = 2048, maxValY = 2048;
  static float lastValX = 0;
  static float lastValY = 0;
  constexpr float offset = 1.f;
    
  std::random_device rd;
  std::default_random_engine gen(rd());
    
  if (!first_time) {
    maxValX = lastValX + offset;
    minValX = lastValX - offset;
    maxValY = lastValY + offset;
    minValY = lastValY - offset;
  }
    
  std::uniform_real_distribution<float> distX(minValX, maxValX);
  std::uniform_real_distribution<float> distY(minValY, maxValY);
  lastValX = distX(gen);
  lastValY = distY(gen);
  if (first_time) first_time = false;
  return { lastValX, lastValY };
}

namespace Utils
{
  float Disatance(float currX, float currY, float needX, float needY)
  {
    return std::hypot(currX - needX, currY - needY);
  };
}

void writeSomeShit()
{
  // сколько знаков после запятой нужно
  constexpr auto precision = 2;
  if (isLocalPlayerMove(Forward_or_Backward) || isPlayerMove(Left_or_Right)) {
    static ULONGLONG iTick = GetTickCount();
    if (GetTickCount() - iTick > static_cast<ULONGLONG>(2000)) {
      // чтобы не ебать фс каждую итерацию или вообще лишний раз
      // то открываем файл только если все звёзды сошлись
      // и открываем в режиме append, чтобы не переписывать содержимое
      std::ofstream file("n1ght.txt", std::ios_base::app);
      // если файл открылся, то пиздуем дальше
      if (file.good()) {
        // лучше один раз вызвать функцию
        auto localPlayerPos = GetLocalPlayerPosition();
        /* ":" - разделительный знак */
        file << std::fixed << std::setprecision(precision) << localPlayerPos.fX << ":" << std::fixed << std::setprecision(precision) << localPlayerPos.fY << std::endl;
        // закрываем файл
        file.close();
      }
      else
        // Если мы здесь, то АЛЯРМ
        throw("Ватафак мазафака сука блять");
      // сброс таймера
      iTick = GetTickCount();
    }
  }
}

void readSomeShit()
{
  // string match
  std::smatch result;
  std::regex reg("(.*):(.*)");
  float posX, posY;
  //Файл откуда берутся координаты
  std::ifstream fileread("n1ght.txt");
  // если файл открылся, то пиздуем дальше
  if (fileread.good()) {
    //временный буффер куда пишем строку
    std::string line;
    // бегаем по строкам
    while (std::getline(fileread, line))
    {
      //Получаем две координаты в виде чисел из регекса и записываем их в result[1] и result[2]
      std::regex_match(line, result, reg);
      // если регекс совпал, то пиздуем дальше
      if (!result.empty())
      {
        //Переводим наши координаты из string в float для дальнейшей работы
        posX = std::stof(result[1]);
        posY = std::stof(result[2]);
        auto localPlayerPos = GetLocalPlayerPosition();
        float dist = Utils::Disatance(localPlayerPos.fX, localPlayerPos.fY, posX, posY);

        //Если дистанция между игроком и точкой меньше 1.5 то мы должны перейти к следующей строке
        if (dist <= 1.5f)
          continue;
      }
    }
  }
}

int main()
{
  // удолим на всякий случай
  std::remove("n1ght.txt");
  std::cout << "Записываю говно" << std::endl;
  static ULONGLONG iTick = GetTickCount();
  while (true) {
    writeSomeShit();
    if (GetTickCount() - iTick > static_cast<ULONGLONG>(50000))
      break;
  }
  std::cout << "Говно записано" << std::endl;
  std::cout << "Вывожу записанное в консось" << std::endl;
  std::ifstream t("file.txt");
  std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());
  std::cout << "Читаю записанное по регексу" << std::endl;
  readSomeShit();
  std::cout << "Прочитал ебать" << std::endl;
}
 
Чел который заливает говно на GitHub
Начинающий
Статус
Оффлайн
Регистрация
2 Фев 2020
Сообщения
37
Реакции[?]
22
Поинты[?]
0
Ах да, и я бы лучше переписал этот BOOBA регекс, а то в таком состоянии оно хавнёт даже: сиси:писи
Вот вариант получче: (-?\d*\.\d{2}):(-?\d*\.\d{2}), где 2 это количество знаков после "запятой" (которое определено у меня переменной constexpr auto precision = 2;) или просто заменить {2} на *
 
Последнее редактирование:
Сверху Снизу