@Steve Townsend już wskazał jedną możliwość. Jeśli wolisz używać operator>>
zamiast std::getline
, możesz to zrobić również. istream
zawsze traktuje spacje jako separator. Każdy strumień ma powiązane ustawienia narodowe, a każde ustawienie narodowe obejmuje aspekt. Ten aspekt polega na tym, że istream
służy do określenia, które znaki wejściowe są białymi znakami.
W twoim przypadku, najwyraźniej chcesz, aby strumień traktował tylko nowe linie i dwukropki jako "białe spacje" (tj. Separatory), podczas gdy rzeczywisty znak spacji jest traktowany jako "normalny" znak, a nie jako separator.
Aby to zrobić, można utworzyć aspekt ctype takiego:
struct field_reader: std::ctype<char> {
field_reader(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(table_size, std::ctype_base::mask());
rc['\n'] = std::ctype_base::space;
rc[':'] = std::ctype_base::space;
return &rc[0];
}
};
użyć, to trzeba "nasycić" strumień z lokalizacji używając ten aspekt:
int main() {
std::stringstream input("A:KT5:14:executive desk:");
// have the stream use our ctype facet:
input.imbue(std::locale(std::locale(), new field_reader()));
// copy fields from the stream to standard output, one per line:
std::copy(std::istream_iterator<std::string>(input),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
Jestem jednak pierwszym, który przyznaje, że ma to pewne wady. Przede wszystkim lokalizacje i aspekty są generalnie słabo udokumentowane, więc większość programistów C++ prawdopodobnie uzna to za dość trudne do zrozumienia (szczególnie, gdy cała prawdziwa praca dzieje się "pod osłonami", że tak powiem).
Inną możliwością jest użycie Boost Tokenizer. Szczerze mówiąc, jest to trochę potrzebne do pracy - wymaga to odczytywania ciągu znaków, a następnie oddzielenia go oddzielnie.Jednocześnie jest dobrze udokumentowany, dość powszechnie znany i lepiej pasuje do ludzkich wyobrażeń o tym, jak robić takie rzeczy, że całkiem sporo osób prawdopodobnie będzie łatwiej je śledzić, pomimo dodatkowej złożoności.
Wow ... i nie w dobry sposób. Myślę, że będę trzymać się C. – onemasse
dzięki Steve !!! – rajh2504
@onemasse, erm: deklaracja faktycznie wygląda następująco: 'istream i getline (istream i is, string & str, char delim);', czy to nie takie złe? :), nie wspominając o tym, co 'std :: getline' daje ci ponad równoważny C! :) – Nim