2010-01-15 9 views
11

Estoy tratando de averiguar cómo puedo analizar esta cadena usando "sstream" y C++Cómo analizar cadenas complejas con C++?

El formato de la misma es: "string, int, int".

Necesito ser capaz de asignar la primera parte de la cadena que contiene una dirección IP a std :: string.

Aquí es un ejemplo de esta cadena:

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

Me continuación, tendrá que obtener

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

voy a mencionar una vez más que no puedo usar boost biblioteca, simplemente sstream :-)

Gracias

+2

Huele a la tarea :) O hay alguna otra razón de por qué no se puede utilizar impulso? – larsmoa

+2

¿Por qué es inusual que no pueda usar boost? En un entorno corporativo, normalmente no se le permite agregar nuevas dependencias de biblioteca al azar, puede tomar meses obtener el permiso o simplemente puede rechazarse. –

+1

O puede usar Boost ... pero tenga una versión anterior. Todavía tengo que usar "1-33-x" gracias a una dependencia anticuada que no ha evolucionado:/ –

Respuesta

3

Aquí hay un útil función de tokenización No utiliza secuencias, pero puede realizar fácilmente la tarea que necesita al dividir la cadena en comas. Luego puedes hacer lo que quieras con el vector resultante de tokens.

/// 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)' no es realmente necesario, 'std :: string :: substr' copia los caracteres hasta el final de la cadena si el número se extiende más allá de su final. http://www.cplusplus.com/reference/string/string/substr/ – Dmitry

+0

Hizo esto la respuesta correcta ya que es un enfoque más general, gracias por este Eli. – Goles

2

que podría hacer algo como esto, así que creo (totalmente fuera de la parte superior de mi cabeza tan disculpas si he cometido algunos errores en allí) ...

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

Si reemplaza istrstream y ontrstream con stringstream y lo inicia de la manera correcta, esto funciona perfectamente. – Goles

+0

La primera parte es una cadena seguida de un comandante. No debe dividir eso en sus partes constitutivas a menos que su equipo le diga que es la dirección IP4 (o algo específico). –

+1

Esto es muy frágil y fallará en cualquier entrada que no coincida exactamente con la estructura de entrada (sin permitir ninguna forma de detección o recuperación de error). Este problema se resolvería mejor con un tokeniser como la publicación de @Eli Bendersky. – gavinb

6

No es de lujo pero se puede usar std :: getline a dividir la cadena:

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

a continuación, se puede extraer la información necesaria de cada una de las cadenas separadas.

+0

Es mucho más fácil no ensuciar que el ejemplo de Eli, aunque limitado a un solo delimitador (que cubre este caso) realmente hace el truco bastante bien. –

12

El C++ String Toolkit Library (Strtk) tiene la siguiente solución a su problema:

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

Más ejemplos se pueden encontrar Here

Cuestiones relacionadas