2012-07-07 19 views
14

C'è un modo per leggere una stringa formattata come questa, ad esempio :48754+7812=Abcs.Il modo più semplice per leggere l'input formattato in C++?

Diciamo che ho tre Stringz X, Y e Z, e voglio

X = 48754 
Y = 7812 
Z = Abcs 

Le dimensioni dei due numeri e la lunghezza della stringa può variare, in modo da non voglio usare substring() o niente come quello.

E 'possibile dare C++ un parametro come questo

":#####..+####..=SSS.." 

quindi conosce direttamente cosa sta succedendo?

risposta

11

Una possibilità è boost::split(), che permette di specificare più delimitatori e non richiede la conoscenza preventiva della dimensione dell'input:

#include <iostream> 
#include <vector> 
#include <string> 

#include <boost/algorithm/string.hpp> 
#include <boost/algorithm/string/split.hpp> 

int main() 
{ 
    std::vector<std::string> tokens; 
    std::string s(":48754+7812=Abcs"); 
    boost::split(tokens, s, boost::is_any_of(":+=")); 

    // "48754" == tokens[0] 
    // "7812" == tokens[1] 
    // "Abcs" == tokens[2] 

    return 0; 
} 

Oppure, con sscanf():

#include <iostream> 
#include <cstdio> 

int main() 
{ 
    const char* s = ":48754+7812=Abcs"; 
    int X, Y; 
    char Z[100]; 

    if (3 == std::sscanf(s, ":%d+%d=%99s", &X, &Y, Z)) 
    { 
     std::cout << "X=" << X << "\n"; 
     std::cout << "Y=" << Y << "\n"; 
     std::cout << "Z=" << Z << "\n"; 
    } 

    return 0; 
} 

Tuttavia, il limite qui è che la lunghezza massima della stringa (Z) deve essere decisa prima di analizzare l'input.

+0

Grazie mille per la risposta ma c'è qualcos'altro oltre a boost o eventuali librerie esterne .. è possibile essere fatto in standard C++ o almeno stl –

+0

@LoersAntario, risposta aggiornata. – hmjd

+0

Potrebbe fare un downstream per favore spiegare? – hmjd

2

per esempio.

#include <boost/regex.hpp> 
#include <iostream> 

int main() 
{ 
    boost::regex re("\":(\\d+)\\+(\\d+)=(.+)\""); 
    std::string example = "\":48754+7812=Abcs\""; 
    boost::smatch match; 
    if (boost::regex_match(example, match, re)) 
    { 
     std::cout << "f number: " << match[1] << " s number: " << match[2] << " string: " << match[3] 
     << std::endl; 
    } 
    else 
    { 
     std::cout << "not match" << std::endl; 
    } 
} 

e seconda variante, funziona solo con stringa.

#include <string> 
#include <iostream> 

int main() 
{ 
    std::string s = "\":48754+7812=Abcs\""; 
    std::string::size_type idx = s.find(":"); 
    std::string::size_type end_first = s.find("+", idx + 1); 
    std::string f_number = s.substr(idx + 1, end_first - (idx + 1)); 
    std::cout << f_number << std::endl; 
    std::string::size_type end_second = s.find("=", end_first + 1); 
    std::string s_number = s.substr(end_first + 1, end_second - (end_first + 1)); 
    std::cout << s_number << std::endl; 
    std::string::size_type string_end = s.find("\"", end_second); 
    std::string str = s.substr(end_second + 1, string_end - (end_second + 1)); 
    std::cout << str << std::endl; 
} 
+0

+1 per suggerire espressioni regolari –

+1

Le espressioni regolari sono un buon suggerimento in molti di questi casi, +1 per quello. Nota che il supporto alle espressioni regolari è, comunque, disponibile come parte di C++ in C++ 11 - non c'è più bisogno di usare l'espressione regolare Boost. – jogojapan

+1

@jogojapan non ora = (http://liveworkspace.org/code/b66dcfa19ce7620fb7b9e4c203c42f43 – ForEveR

11
#include <iostream> 
#include <sstream> 

int main(int argc, char **argv) { 
    std::string str = ":12341+414112=absca"; 
    std::stringstream ss(str); 
    int v1, v2; 
    char col, op, eq; 
    std::string var; 
    ss >> col >> v1 >> op >> v2 >> eq >> var; 
    std::cout << v1 << " " << v2 << " " << var << std::endl; 
    return 0; 
} 
+2

+1 perché questa è l'unica risposta che prende precisamente in considerazione la domanda reale.Le altre risposte no, perché ** 1 usare boost non è il modo più semplice ** (ammetto che potrebbe essere il modo più eloquente) e ** 2. scanf non è in stile C++ ** (come citato dall'autore della risposta corrispondente). – ChristophK

3

È possibile utilizzare scanf. E non è eccessivamente C++ - ish, ma fa il trucco con pochissime righe di codice:

char a[101], b[111], c[121]; 
sscanf(":48754+7812=Abcs", ":%100[^+]+%110[^=]=%120s", a, b, c); 
string sa(a), sb(b), sc(c); 
cout << sa << "-" << sb << "-" << sc << endl; 

L'idea è quella di specificare i caratteri accettati dalle stringhe che hai letto utilizzando una sintassi delle espressioni regolari molto limitato. In questo caso, la prima stringa viene letta fino al segno più, e la seconda stringa viene letta fino al segno di uguale.

Problemi correlati