Что мне использовать вместо sscanf?

У меня есть проблема, которую решает sscanf (извлечение элементов из строки). Мне не нравится sscanf, так как он не является типобезопасным, старым и ужасным. Я хочу быть умным и использовать некоторые более современные части стандартной библиотеки C++. Что я должен использовать вместо этого?


person Ben Hymers    schedule 23.06.2009    source источник
comment
Например, по той причине, что он сказал, что sscanf не является типобезопасным.   -  person jalf    schedule 23.06.2009
comment
@Kaleb Pederson: Для многих англоговорящих умный может просто означать умный и не имеет негативного оттенка, который иногда имеет в США. Обратите внимание, что Бен Хаймерс из Великобритании.   -  person Naaff    schedule 23.06.2009
comment
Умный имеет отрицательный оттенок? Наверное, это что-то говорит о США. Я не уверен, что, хотя. Да, я имел в виду умный :)   -  person Ben Hymers    schedule 24.06.2009
comment
@BenHymers Если подумать, да, в США умный иногда используется с оттенком иронии, чтобы означать что-то вроде творческого, но непослушного. В этом смысле самомодифицирующийся код можно назвать умным.   -  person Nathan Monteleone    schedule 22.06.2016
comment
Да все верно. Обсуждение умного против умного гораздо важнее :)   -  person Utkarsh Kumar    schedule 29.06.2017


Ответы (5)


Попробуйте std::stringstream:

#include <sstream>

...

std::stringstream s("123 456 789");
int a, b, c;
s >> a >> b >> c;
person Fred Larson    schedule 23.06.2009
comment
как узнать, если c нет, например, строка была 123 456? - person unludo; 26.07.2012
comment
@unludo: в этом случае c останется без изменений. Вы можете инициализировать c значением по умолчанию или вам может потребоваться более сложный синтаксический анализ. Токенизатор, вероятно, сработает. - person Fred Larson; 27.07.2012
comment
Начиная с C++11, c будет сброшено на 0, а до этого я считаю, что его значение после сбоя было неопределенным. В любом случае, чтобы проверить, есть ли c, используйте состояние потока (для удобства из operator bool()): if (s >> a >> b) if (s >> c ) abc_there(); else ab_there(); else didnt_have_a_and_b();. - person Tony Delroy; 25.03.2016

Стандартные потоки отлично справляются с большинством задач,

std::string data = "AraK 22 4.0";
std::stringstream convertor(data);
std::string name;
int age;
double gpa;

convertor >> name >> age >> gpa;

if(convertor.fail() == true)
{
    // if the data string is not well-formatted do what ever you want here
}

Если вам нужны более мощные инструменты для более сложного синтаксического анализа, вы можете рассмотреть Regex или даже Spirit от Boost.

person AraK    schedule 23.06.2009

Если вы включите sstream, у вас будет доступ к классам stringstream, которые предоставляют потоки для строк, что вам и нужно. У Roguewave есть несколько хороших примеров того, как его использовать. .

person Kaleb Pederson    schedule 23.06.2009

Если вы действительно хотите не использовать потоки (это хорошо из-за удобочитаемости), вы можете использовать StringPrintf.

Вы можете найти его реализацию в Folly:

https://github.com/facebook/folly/blob/master/folly/String.h#L165

person iampat    schedule 07.08.2013
comment
Хороший кусок кода (я уже использую что-то почти такое же), хотя это замена printf, а не sscanf. - person Ben Hymers; 08.08.2013

fgets или strtol

person joe    schedule 23.06.2009