2010-01-15 2 views
11

Я пытаюсь выяснить, как я могу разобрать эту строку, используя «sstream» и C++Как разобрать сложную строку с C++?

Формат: «строка, int, int».

Мне нужно уметь назначить первую часть строки, которая содержит IP-адрес, в std :: string.

Вот пример этой строки:

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

Я тогда должен был бы получить

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

Назову еще раз, что я не могу использовать boost библиотеку, просто sstream :-)

Thanks

+2

Пахнет домашнее задание :) Или есть другая причина, почему вы не можете использовать импульс? – larsmoa

+2

Почему это необычно, он не может использовать boost? В корпоративной среде вам обычно не позволяют случайным образом добавлять новые зависимости в библиотеке, для получения разрешения могут потребоваться месяцы, или их можно просто отклонить. –

+1

Или вы можете использовать Boost ... но застрять с ранней версией. Я все еще должен использовать «1-33-x» благодаря старой иждивенческой зависимости, которая не развивалась:/ –

ответ

3

Полезная информация функция токенизации. Он не использует потоки, но может легко выполнить требуемую задачу, разделив строку на запятую. Затем вы можете делать все, что хотите, с результирующим вектором токенов.

/// 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)' на самом деле не требуется, 'std :: string :: substr' копирует символы до конца строки, если число проходит через конец. http://www.cplusplus.com/reference/string/string/substr/ – Dmitry

+0

Сделал правильный ответ, потому что это более общий подход, спасибо за этот Эли. – Goles

2

Вы могли бы сделать что-то подобное, а я верю (Totally с верхней части моей головы так извинениями, если я сделал некоторые ошибки в там) ...

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

Если вы замените istrstream и ontrstream строковым потоком и запустите его правильно, это отлично работает. – Goles

+0

Первая часть - это строка, за которой следует запятая. Вы не должны разделять это на свои составные части, если только кто-то не сообщит вам свой IP4-адрес (или что-то конкретное). –

+1

Это очень хрупок и не будет работать на любом входе, который точно не соответствует структуре ввода (без учета разумной формы обнаружения ошибок или восстановления). Эта проблема будет лучше решена с помощью токенизатора, такого как сообщение by @Eli Bendersky. – gavinb

6

Это не фантазии но вы можете использовать зЬй :: GetLine разбить строку:

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); 
} 

Затем вы можете извлечь необходимую информацию из каждого из разделенных строк.

+0

Это намного проще не испортить, чем пример Эли, хотя он ограничен только одним разделителем (который охватывает этот случай), он действительно делает этот трюк довольно аккуратно. –

12

C++ String Toolkit Library (Strtk) имеет следующее решение проблемы:

 
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; 
} 

Больше примеров можно найти Here

Смежные вопросы