Самый простой способ прочитать форматированный ввод в C ++?

Есть ли способ прочитать отформатированную строку, как это, например,:48754+7812=Abcs.

Допустим, у меня есть три строки Z, Y и Z, и я хочу

X = 48754 
Y = 7812
Z = Abcs

Размер двух чисел и длина строки могут отличаться, поэтому я не хочу использоватьsubstring() или что-нибудь в этом роде.

Можно ли дать C ++ такой параметр

":#####..+####..=SSS.."

так что он точно знает, что происходит?

Ответы на вопрос(4)

#include <iostream>
#include <sstream>

int main(int argc, char **argv) {
  std::string str = ":12341+414112=absca";
  std::stringstream ss(str);
  int v1, v2; 
  char col, op, eq; 
  std::string var;
  ss >> col >> v1 >> op >> v2 >> eq >> var;
  std::cout << v1 << " " << v2 << " " << var << std::endl;
  return 0;
}
 03 нояб. 2015 г., 12:25
+1, потому что это единственный ответ, который точно учитывает актуальный вопрос. Другие ответы не имеют, потому что1. using boost is not the simplest way (Я признаю, что это может быть самый изящный способ) и2. scanf is not C++ style (как указано автором соответствующего ответа).
Решение Вопроса

boost::split(), который позволяет задавать несколько разделителей и не требует предварительного знания размера входных данных:

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

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>

int main()
{
    std::vector<std::string> tokens;
    std::string s(":48754+7812=Abcs");
    boost::split(tokens, s, boost::is_any_of(":+="));

    // "48754" == tokens[0]
    // "7812"  == tokens[1]
    // "Abcs"  == tokens[2]

    return 0;
}

Или, используяsscanf():

#include <iostream>
#include <cstdio>

int main()
{
    const char* s = ":48754+7812=Abcs";
    int X, Y;
    char Z[100];

    if (3 == std::sscanf(s, ":%d+%d=%99s", &X, &Y, Z))
    {
        std::cout << "X=" << X << "\n";
        std::cout << "Y=" << Y << "\n";
        std::cout << "Z=" << Z << "\n";
    }

    return 0;
}

Тем не менее, ограничение здесь заключается в том, что максимальная длина строки (Z) должно быть решено до разбора ввода.

 07 июл. 2012 г., 13:43
@LoersAntario, обновленный ответ.
 09 авг. 2012 г., 12:22
Может ли downvoter объяснить, пожалуйста?
 Loers Antario07 июл. 2012 г., 13:40
большое спасибо за ответ, но есть ли что-то еще, кроме boost или каких-либо внешних библиотек ... это можно сделать в стандартном c ++ или по крайней мере в stl

scanf, Это не слишком C ++ - иш, но он справляется с замечательно небольшим количеством строк кода:

char a[101], b[111], c[121];
sscanf(":48754+7812=Abcs", ":%100[^+]+%110[^=]=%120s", a, b, c);
string sa(a), sb(b), sc(c);
cout << sa << "-" << sb  << "-" << sc << endl;

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


#include <boost/regex.hpp>
#include <iostream>

int main()
{
   boost::regex re("\":(\\d+)\\+(\\d+)=(.+)\"");
   std::string example = "\":48754+7812=Abcs\"";
   boost::smatch match;
   if (boost::regex_match(example, match, re))
   {
      std::cout << "f number: " << match[1] << " s number: " << match[2] << " string: " << match[3]
      << std::endl;
   }
   else
   {
      std::cout << "not match" << std::endl;
   }
}

и второй вариант, работа только со строкой.

#include <string>
#include <iostream>

int main()
{
   std::string s = "\":48754+7812=Abcs\"";
   std::string::size_type idx = s.find(":");
   std::string::size_type end_first = s.find("+", idx + 1);
   std::string f_number = s.substr(idx + 1, end_first - (idx + 1));
   std::cout << f_number << std::endl;
   std::string::size_type end_second = s.find("=", end_first + 1);
   std::string s_number = s.substr(end_first + 1, end_second - (end_first + 1));
   std::cout << s_number << std::endl;
   std::string::size_type string_end = s.find("\"", end_second);
   std::string str = s.substr(end_second + 1, string_end - (end_second + 1));
   std::cout << str << std::endl;
}
 07 июл. 2012 г., 16:10
@ForEveR Верно. Я должен был проверить, но на самом деле поддержка регулярных выражений в GCC все еще не там, где она должна быть, особенно. группы захвата не работают. Кроме того, существуют различия в синтаксисе регулярных выражений. Например. стандартный способ сделать[\d] в С ++ 11 есть[[:digit:]], В любом случае, в качестве последнего комментария, поддержка регулярного выражения в C ++ 11 лучше, если вы используете Clang. При правильной настройке синтаксиса ваш пример кода должен работать там.
 07 июл. 2012 г., 15:16
 07 июл. 2012 г., 13:41
+1 за предложение регулярных выражений
 07 июл. 2012 г., 14:09
Регулярные выражения являются хорошим предложением во многих таких случаях, +1 за это. Обратите внимание, что поддержка регулярных выражений доступна как часть C ++ в C ++ 11 - больше нет необходимости использовать Boost regex.

Ваш ответ на вопрос