Разбор пользовательской строки в 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
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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';
}

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