2010-01-15 12 views
11

Próbuję dowiedzieć się, jak można przeanalizować ten ciąg przy użyciu "sstream" i C++Jak przeanalizować złożony ciąg znaków w C++?

Format to: "string, int, int".

Potrzebuję być w stanie przypisać pierwszą część ciągu, który zawiera adres IP do std :: string.

Oto przykład tego komunikatu:

std::string("127.0.0.1,12,324"); 

bym wtedy trzeba uzyskać

string someString = "127.0.0.1"; 
int aNumber = 12; 
int bNumber = 324; 

Wspomnę jeszcze, że nie mogę używać boost bibliotekę, tylko sstream :-)

Dzięki

+2

Pachnie jak praca domowa :) A może jest jakiś inny powód, dlaczego nie można używać impuls? – larsmoa

+2

Dlaczego jest to niezwykłe, że nie może użyć wzmocnienia? W środowisku korporacyjnym zazwyczaj nie można losowo dodawać nowych zależności bibliotek, może to zająć miesiące, aby uzyskać pozwolenie lub może po prostu zostać odrzucone. –

+1

Możesz też użyć funkcji Boost ..., ale utknij w wersji wczesnej. Nadal muszę używać "1-33-x" dzięki starej zależności, która nie ewoluowała:/ –

Odpowiedz

3

Oto przydatne funkcja tokenizacji. Nie używa strumieni, ale może łatwo wykonać żądane zadanie, dzieląc ciąg znaków na przecinki. Następnie możesz zrobić, co chcesz, z powstałym wektorem tokenów.

/// String tokenizer. 
/// 
/// A simple tokenizer - extracts a vector of tokens from a 
/// string, delimited by any character in delims. 
/// 
vector<string> tokenize(const string& str, const string& delims) 
{ 
    string::size_type start_index, end_index; 
    vector<string> ret; 

    // Skip leading delimiters, to get to the first token 
    start_index = str.find_first_not_of(delims); 

    // While found a beginning of a new token 
    // 
    while (start_index != string::npos) 
    { 
     // Find the end of this token 
     end_index = str.find_first_of(delims, start_index); 

     // If this is the end of the string 
     if (end_index == string::npos) 
      end_index = str.length(); 

     ret.push_back(str.substr(start_index, end_index - start_index)); 

     // Find beginning of the next token 
     start_index = str.find_first_not_of(delims, end_index); 
    } 

    return ret; 
} 
+0

'if (end_index == string :: npos)' nie jest tak naprawdę konieczne, 'std :: string :: substr' kopiuje zwiastuny aż do końca łańcucha, jeśli liczba przekroczyła koniec. http://www.cplusplus.com/reference/string/string/substr/ – Dmitry

+0

To poprawna odpowiedź, ponieważ jest to bardziej ogólne podejście, dziękuję ci za to Eli. – Goles

2

Można zrobić coś takiego jak wierzę (Totally off górze mojej głowie tak przeprosin jeśli zrobiłem kilka błędów w tam) ...

stringstream myStringStream("127.0.0.1,12,324"); 
int ipa, ipb, ipc, ipd; 
char ch; 
int aNumber; 
int bNumber; 
myStringStream >> ipa >> ch >> ipb >> ch >> ipc >> ch >> ipd >> ch >> aNumber >> ch >> bNumber; 

stringstream someStringStream; 
someStringStream << ipa << "." << ipb << "." << ipc << "." << ipd; 
string someString(someStringStream.str()); 
+0

Jeśli zamienisz istrstream i ontrstream na stringstream i zainicjujesz go we właściwy sposób, działa to doskonale. – Goles

+0

Pierwsza część to ciąg, po którym następuje komenda. Nie należy dzielić tego na części składowe, chyba że sombody powie ci jego adres IP4 (lub coś konkretnego). –

+1

To jest bardzo delikatne i nie powiedzie się na żadnym wejściu, które nie pasuje dokładnie do struktury wejściowej (bez umożliwienia jakiejkolwiek zdrowej formy wykrywania lub odzyskiwania błędów). Ten problem byłby lepiej rozwiązany dzięki tokeniserowi, na przykład dzięki @Eli Bendersky. – gavinb

6

To nie jest wyszukane ale można użyć std :: getline podzielić ciąg:

std::string example("127.0.0.1,12,324"); 
std::string temp; 
std::vector<std::string> tokens; 
std::istringstream buffer(example); 

while (std::getline(buffer, temp, ',')) 
{ 
    tokens.push_back(temp); 
} 

Następnie można wyodrębnić niezbędnych informacji od każdego z wydzielonych ciągów.

+0

Znacznie łatwiej jest nie zepsuć niż przykład Eli, choć ograniczony do tylko jednego ogranicznika (który obejmuje ten przypadek), to naprawdę całkiem dobrze. –

12

C++ String Toolkit Library (Strtk) ma następujące rozwiązanie problemu:

 
int main() 
{ 
    std::string data("127.0.0.1,12,324"); 
    string someString; 
    int aNumber; 
    int bNumber; 
    strtk::parse(data,",",someString,aNumber,bNumber); 
    return 0; 
} 

Więcej przykładów można znaleźć Here

Powiązane problemy