Разбор пользовательской строки в C++

У меня есть строка типа:


"../blabla/here_is_same0000:00/0000:00:1A.0/blabla/blabla/blabla"

Я хочу получить часть 1A.0 из строки и вернуться в виде десятичного числа. Эти места всегда идут после шаблона here_is_same0000:00. Также эти места (0000:00:1A.0) не всегда занимают третье место в данной строке.

Я написал такой код:

static const std::string test_str1{"../blabla/here_is_same0000:00/0000:00:1A.0/blabla/blabla/blabla"};

std::tuple<int, int> values(const std::string& in)
{
  static const std::string constant_pattern{"here_is_same0000:00"};
  std::size_t found_idx = in.find(constant_pattern);
  if (found_idx == std::string::npos)
  {
    return std::make_tuple(0,0);
  }

  std::string remaining = in.substr(found_idx + constant_pattern.length() + 1, in.length());
  
  found_idx = remaining.find("/");
  if (found_idx == std::string::npos)
  {
    return std::make_tuple(0,0);
  }

  remaining = remaining.substr(0, found_idx);
  found_idx = remaining.find_last_of(":");
  remaining = remaining.substr(found_idx + 1, remaining.length());

  std::stringstream ss(remaining);
  std::string items;
  std::vector<std::string> elements;
  while(std::getline(ss, items, '.'))
  {
    elements.push_back(std::move(items));
  }

  int x;
  std::stringstream ss_convert_x;
  ss_convert_x << std::hex << elements[0];
  ss_convert_x >> x;
  
  int y;
  std::stringstream ss_convert_y;
  ss_convert_y << std::hex << elements[1];
  ss_convert_y >> y;

  std::cout << x <<" "<< y;
  
  return std::make_tuple(x,y);
}

Но мне это кажется плохим, есть ли лучший способ?

Почему тебе это кажется плохим? Что вы имеете ввиду под "лучше"?

463035818_is_not_a_number 22.02.2023 08:36

Как насчет использования регулярного выражения для синтаксического анализа?

πάντα ῥεῖ 22.02.2023 08:38

Это работает? Тогда оставь это. Если у вас нет не пройденного теста или какого-то объективного критерия, которому код не соответствует, вы не должны его трогать. "выглядит плохо" не является объективным критерием. Вы можете изменить код, и нет четкого способа определить, улучшило ли это изменение или нет.

463035818_is_not_a_number 22.02.2023 08:38

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

john 22.02.2023 08:38

Чтобы проанализировать пользовательскую строку в C++, вам нужно будет использовать библиотеку std::string. Эта библиотека предоставляет множество полезных методов для работы со строками, например, метод substr(), который можно использовать для извлечения подстрок из строки. Кроме того, вы можете использовать класс std::stringstream для разбора строки с помощью оператора >>. Этот класс предоставляет различные методы для преобразования строковых объектов в различные типы, такие как int, float, double и т. д. Наконец, вы можете использовать метод find() для поиска определенного символа или подстроки в строке.

Prabhat Sinha 22.02.2023 08:59

Я хочу написать этот код более читаемым @463035818_is_not_a_number

embeddedstack 22.02.2023 09:07

Не могли бы вы привести пример регулярного выражения для строки, которую я упомянул в вопросе @πάνταῥεῖ

embeddedstack 22.02.2023 09:09
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и...
Введение в раздел &quot;Заголовок&quot; в HTML
Введение в раздел "Заголовок" в HTML
Говорят, что лучшее о человеке можно увидеть только изнутри, и это относится и к веб-страницам HTML! Причина, по которой некоторые веб-страницы не...
0
7
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как уже упоминалось другими и даже предложено вашим термином «шаблон», «регулярное выражение» - это путь.

В этом случае вы можете просто использовать std::regex_search. Пожалуйста, прочитайте об этом здесь.

Преимущество заключается в том, что если функция поиска возвращает результат, вы можете быть уверены, что числа указаны в правильном формате. Так что функция std::stoi будет работать всегда.

Регулярное выражение можно разработать с помощью страницы онлайн-тестирования регулярных выражений, такой как regex101.

Тогда реализация будет очень простой. См. приведенный ниже пример:

#include <iostream>
#include <string>
#include <regex>
#include <tuple>

const std::string test{"../blabla/here_is_same0000:00/0000:00:1A.0/blabla/blabla/blabla"};

const std::regex re{R"(.*?here_is_same0000:00/0000:00:([0-9a-fA-F]+)\.(\d).*)"};

std::tuple<int, int> values(const std::string& in) {
    
    std::tuple<int, int> result{};
    if (std::smatch sm{};std::regex_search(test, sm, re))
        result = {std::stoi(sm[1],nullptr,16),std::stoi(sm[2])};
    return result;
}

int main() {
    const auto& [i1,i2] = values(test);
    std::cout << i1 << ' ' << i2 << '\n';
}

Другие вопросы по теме