2016-09-08 3 views
1

Ich versuche eine Möglichkeit zu finden, eine Zeichenfolge zu teilen, um Zahlen und bestimmte Wörter zu finden. Hier versuche ich die Anzahl der Äpfel und Orangen zu lesen. So wie ich das geschrieben habe, wenn das Wort "Apfel" oder "Orange" vor oder nach Satzzeichen steht, zählt es nicht. Betrachten Sie zum Beispiel die Textdatei:C++ int und String-Parsing mit Trennzeichen

3 Äpfel 2 Orangen
3 Äpfel. 2 Orangen.
(3 Äpfel 2 Orangen)

Dieses Programm wird nur die erste Zeile abrechnen, da es keine Interpunktion gibt. Ich hatte gehofft, jemand könnte mir eine bessere Herangehensweise an dieses Problem zeigen.

#include <iostream> 
#include <string> 
#include <fstream> 
#include<sstream> 
using namespace std; 

void readString(string line, int& a, int& o); 
//splits the string up into substrings 

void assignValue(string str, int& a, int& o, int v); 
// takes the word following the value and decides whether to assign it to  apples, oranges, or neither 

int main() 
{ 
    ifstream inStream; 
    inStream.open(name_of_file); 

    int apples = 0, oranges = 0; 
    string line; 

    while (!(inStream.eof())) 
    { 
     getline(inStream, line); 
     readString(line, apples, oranges); 
    } 

    cout << "Apples:" << apples << endl; 
    cout << "Oranges" << oranges << endl; 

    inStream.close(); 

    system("pause"); 
    return 0; 
} 

    void readString(string l, int& a, int& o) 
    { 
     stringstream ss(l); 
     string word; 
     int value = 0; 

     while (ss >> word) 
     { 
      istringstream convert(word 
      if (convert >> value)       
      { 
       ss >> word;       
       assignValue(word, a, o, value);    
      } 
     } 
    } 

    void assignValue(string str, int& a, int& o, int v) 
    { 
     if (str == "apples") 
     { 
      a += v; 
     } 
     if (str == "oranges") 
     { 
      o += v; 
     } 
    } 
+1

als beiseite. Anstelle von while (! (InStream.eof())) 'sollten Sie einfach' if (inStream >> line) 'verwenden, da' eof' nicht auf Fehler prüft, sondern nur auf das Ende der Datei. Siehe [hier] (http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-sidered-wrong). –

Antwort

0

Es sieht für mich wie alles, was gebraucht hier ist jede Interpunktion in der Zeichenfolge in Leerzeichen zu ersetzen, bevor Sie Ihren bestehenden Parsing-Code ausgeführt wird, die schön die Zeichenfolge in Leerzeichen getrennte Wörter zerhacken wird.

Definieren wir "Interpunktion" als "alles andere als ein Buchstabe oder eine Zahl".

können Sie verwenden std::replace_if() in readString(), bevor er seine Konstrukte std::stringstream:

std::replace_if(l.begin(), l.end(), [](char c) { return !isalnum(c) }, ' '); 

Oder, wenn Sie ausdrücklich ein wenig sein mag:

for (char &c:l) 
{ 
    if (!isalnum(c)) 
     c=' '; 
} 

Nun, das alle Interpunktion jetzt durch Leerzeichen ersetzt, sollte der vorhandene Code, den Sie dort haben, danach gut aufräumen.

Eine mögliche Komplikation hier wäre, wenn Ihre numerischen Werte gebrochen sein könnten. Da Sie sie als int deklariert haben, kann dies nicht der Fall sein. Aber, wenn Sie etwas wie "4.5 Äpfel" als Eingabe akzeptieren müssen, erfordert dies natürlich zusätzliche Arbeit, da dieser Code die Periode glücklich durch ein Leerzeichen ersetzt. Aber das ist nur eine mentale Notiz, die man im Kopf behalten sollte.

Verwandte Themen