У меня есть проблема, которую решает sscanf (извлечение элементов из строки). Мне не нравится sscanf, так как он не является типобезопасным, старым и ужасным. Я хочу быть умным и использовать некоторые более современные части стандартной библиотеки C++. Что я должен использовать вместо этого?
Что мне использовать вместо sscanf?
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
как узнать, если c нет, например, строка была 123 456?
- person unludo; 26.07.2012
@unludo: в этом случае
c
останется без изменений. Вы можете инициализировать c
значением по умолчанию или вам может потребоваться более сложный синтаксический анализ. Токенизатор, вероятно, сработает.
- person Fred Larson; 27.07.2012
Начиная с 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
Хороший кусок кода (я уже использую что-то почти такое же), хотя это замена
printf
, а не sscanf
.
- person Ben Hymers; 08.08.2013
fgets или strtol
person
joe
schedule
23.06.2009