2017-02-02 3 views
0

Wie wird die Zeichenfolge in zwei Teile aufgeteilt, nachdem ich die Operation dem Operator math zugewiesen habe? Zum Beispiel 4567 * 6789 möchte ich String in drei Teil Erste aufzuspalten: 4567 Operation: * Zweiter: 6789 Eingang ist von Text-DateiSplit String mit mathematischem Ausdruck

char operation; 
while (getline(ifs, line)){ 

    stringstream ss(line.c_str()); 
    char str; 

    //get string from stringstream 
    //delimiter here + - */to split string to two part 

    while (ss >> str) { 
     if (ispunct(str)) { 
      operation = str; 
     } 
    } 
} 
+0

Sie müssen wahrscheinlich einen Parser. Such dir Yacc oder Bison an. –

+0

Mögliches Duplikat von [Teilen einer Zeichenkette in C++?] (Http://stackoverflow.com/questions/236129/split-a-string-in-c) – Jonas

+0

Dank ich fand heraus, dass der Zeichenkette Strom aufhört, zu lesen, wenn unterschiedliche Art trifft. –

Antwort

2

Vielleicht, nur vielleicht, durch das Denken aus, wir kommen mit eine Lösung.

Wir wissen, dass operator>> die Verarbeitung beenden wird, wenn auf ein Zeichen trifft, das keine Ziffer ist. Also können wir diese Tatsache nutzen.

int multiplier = 0; 
ss >> multiplier; 

Die nächsten Zeichen sind keine Ziffern, sie könnten also ein Operatorzeichen sein.
Was passiert, wenn wir in einem Zeichen lesen:

char operation = '?'; 
ss >> operation; 

Oh, ich vergaß zu erwähnen, dass die operator>> Räume, die durch Standard überspringen wird.

Schließlich können wir Eingang die zweite Zahl:

int multiplicand = 0; 
ss >> multiplicand; 

Um zu bestätigen, lassen Sie uns auszudrucken, was wir in gelesen haben:

std::cout << "First Number: " << multiplier << "\n"; 
std::cout << "Operation : " << operation << "\n"; 
std::cout << "Second Number: " << multiplicand << "\n"; 

Mit einem Debugger hier zeigen wird dazu beitragen, was geschieht, wie jede Aussage ausgeführt wird, eins nach dem anderen.

Edit 1: Kompliziertere
Sie können immer komplizierter und verwenden Sie einen Parser, Lexer oder schreiben Sie Ihre eigenen. Eine gute Methode zur Implementierung ist die Verwendung einer Zustandsmaschine.

Zum Beispiel würden Sie ein einzelnes Zeichen lesen und dann entscheiden, was damit zu tun ist, abhängig vom Status. Wenn das Zeichen beispielsweise eine Ziffer ist, möchten Sie möglicherweise eine Zahl erstellen. Für ein Zeichen (außer Leerraum), wandeln Sie es in ein Token um und speichern Sie es irgendwo.

Es gibt Syntaxbäume und andere Datenstrukturen, die den Vorgang des Parsens erleichtern können. Es gibt auch Parsing-Bibliotheken wie boost::spirit, Yacc, Bison, Flex und Lex.

0

Eine Möglichkeit ist:

char opr; 
int firstNumber, SecondNumber; 
ss>>firstNumber>>opr>>SecondNumber; 

statt:

while (ss >> str) { 
    if (ispunct(str)) { 
     operation = str; 
    } 
} 

Oder mit regex für komplexe expersions. Here ist ein Beispiel für die Verwendung von Regex in Mathematik-Experimenten.

0

Wenn Sie eine Zeichenfolge zur Hand haben, können Sie spalten einfach die Zeichenfolge in links und rechts an der Position des Bedieners, wie folgt:

char* linePtr = strdup("4567*6789"); // strdup to preserve original value 
char* op = strpbrk(linePtr, "+-*"); 
if (op) { 
    string opStr(op,1); 
    *op = 0x0; 
    string lhs(linePtr); 
    string rhs(op+1); 
    cout << lhs << " " << opStr << " " << rhs; 
} 
0

Eine einfache Lösung wäre die Verwendung sscanf:

int left, right; 
char o; 
if (sscanf("4567*6789", "%d%c%d", &left, &o, &right) == 3) { 
    // scan valid... 
    cout << left << " " << o << " " << right; 
} 
0

Meine proposual ist auf Funktionen zu erstellen:

std::size_t delimiter_pos(const std::string line) 
{ 
    std::size_t found = std::string::npos; 
    (found = line.find('+')) != std::string::npos || 
    (found = line.find('-')) != std::string::npos || 
    (found = line.find('*')) != std::string::npos || 
    (found = line.find('/')) != std::string::npos; 
    return found; 
} 

Und zweitens Funkt Ion, das Operanden berechnen:

void parse(const std::string line) 
{ 
    std::string line; 
    std::size_t pos = delimiter_pos(line); 
    if (pos != std::string::npos) 
    { 
     std::string first = line.substr(0, pos); 
     char operation = line[pos]; 
     std::string second = line.substr(pos + 1, line.size() - (pos + 1)); 
    } 
} 

Ich hoffe, dass Sie meine Beispiele geholfen

+0

Führt zu Problemen mit Eingaben wie "1 * 2 + 3". Die Suche nach '+' findet und gibt 3 zurück, also teilt der Aufrufer die Zeichenfolge "1 * 2", "+", "3", was nicht ganz richtig ist. Kommt dir aber sehr nahe. Rufen Sie einfach jeden String an, bis 'npos' zurückgegeben wird. – user4581301