2009-10-31 1 views
6

Так что вы могли бы сделать что-то подобное, например:Можете ли вы рассказать iostreams, какие символы обрабатывать как пробелы?

std::string a("01:22:42.18"); 
std::stringstream ss(a); 
int h, m, s, f; 
ss >> h >> m >> s >> f; 

которое обычно требует строку для форматирования "01 22 42 18". Можете ли вы изменить текущий язык непосредственно, чтобы сделать это?

+0

Я думаю, вы не можете этого сделать. Интересный вопрос, хотя +1 – AraK

ответ

2

Посмотрите на scanf и fscanf. Вы можете * быть в состоянии сделать что-то вроде этого:

int h, m, s, f; 
sscanf(a.c_str(), "%d:%d:%d.%d", &h, &m, &s, &f); 

* Оговорка: Это было какое-то время для меня и C++

+2

Правильно, с использованием 'scanf'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' определенно намного проще. Возможно, вы имели в виду 'sscanf (a.c_str(),"% d:% d:% d.% D ", & h, & m, & s, & f) == 4'. – ephemient

+0

Спасибо, это практическое решение. – henle

+0

@ephemient Ya, это тот. Как я уже сказал, прошло какое-то время с тех пор, как я коснулся любого C/C++ @henle. Если это ваше решение, тогда пометьте его как помощник ответа;) –

2
char c; 
if (!(ss >> h >> c) || c != ':') return; 
if (!(ss >> m >> c) || c != ':') return; 
if (!(ss >> s >> c) || c != '.') return; 
if (!(ss >> f) || ss >> c) return; 
5

Я не думаю, что вы можете изменить разделитель по умолчанию, не создавая новый язык, но это кажется хакерским. То, что вы можете использовать, это использовать getline с третьим параметром, определяющим символ разделителя, или вы можете прочитать разделители и ничего не делать с ними (например, ss >> h >> d >> m >> d >> s >> d> > f).

Вы также можете написать собственный собственный парсинг-класс, который обрабатывает для вас разделительные строки. Или еще лучше, используйте boost::split от Boost's String Algorithms Library.

+0

раздражающая вещь с 'boost :: split' и' getline' заключается в том, что вам нужно разделить строки, а затем вернуть их обратно в поток, чтобы получить целые числа. – henle

+2

Вы можете использовать 'boost :: split' для преобразования 'std :: string' в' std :: vector ', затем используйте' std :: transform' с 'boost :: lexical_cast', чтобы преобразовать' std :: vector 'в' std :: vector < unsigned int> ' –

3

Вы можете сделать это, создав локаль с фаской ctype, классифицирующей : как пробел.

Jerry Coffin explains how you can specify whitespace characters in this answer to another question.

+0

Спасибо, это был бы буквальный ответ на мой вопрос! Хотя я пытаюсь выяснить, можете ли вы просто сделать rc [':'] = std :: ctype_base :: space; , не создавая целую новую локаль ... – henle

+1

К сожалению, поскольку ios_base классифицирует символы как пробельные символы на основе встроенного языка, я не думаю, что есть другие варианты. Предложение Firas boost :: split (или, альтернативно, boost :: tokenizer), вероятно, будет вашим лучшим выбором. –