2017-10-03 1 views
1

Wie kann ich eine Textdatei prüfen, wenn die Daten unter "INSERT_EMPLOYEE" ausreichen, um in meine "insertEmployee" -Funktion eingegeben zu werden? (Beispiel: richtige Zahl, Art der Argumente oder Überprüfung auf Argumentgrenzen) Wenn die Eingabe ein ungültiges Format ist, möchte ich die Operation nicht ausführen, sondern gehe einfach zur nächsten Operation.Funktionsaufruf, der nach Eingabe-Korrektheit aus Textdatei prüft - C++

Meine Textdatei:

INSERT_EMPLOYEE 
12345 
John 
Smith 
60000 
35 

INSERT_EMPLOYEE 
Chris 
Evans 
70000 

INSERT_EMPLOYEE 
34567 
Michael 
Carter 
50500 
25 

PRINT_ROSTER 

Mein main.cpp:

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

int main() { 
    int id, salary, hours; 
    employeeList list = employeeList(); 
    string line, firstName, lastName; 

    ifstream employeeFile; 
    employeeFile.open("employeeFile.txt"); 
    while(getline(employeeFile, line)) { 
     if (line == "INSERT_EMPLOYEE") { 
      employeeFile >> id >> firstName >> lastName >> salary >> hours; 
      list.insertEmployee(id, firstName, lastName, salary, hours); 
     } 
     if (line == "PRINT_ROSTER") { 
      list.printRoster(); 
     } 
    employeeFile.close(); 
    return 0; 
} 
+1

Sie tun dies, indem Sie 'std :: getline()' verwenden und die Eingabe selbst validieren. Der ">>" formatierte Eingabeextraktionsoperator funktioniert hervorragend, wenn die Eingabe gültig ist. Wenn es nicht ist, haben Sie ein großes Durcheinander in Ihren Händen, das schwer zu entwirren sein wird. Wenn die Eingabevalidierung erforderlich ist, verwenden Sie daher nicht '>>'. Ende der Geschichte. –

+0

@SamVarshavchik Das macht vollkommen Sinn, danke! –

+0

Grammatik Hinweis: "_inputted_ in meine" insertEmployee "-Funktion?". Probieren Sie den formelleren Wert "value to insertEmployee()" aus, übergeben Sie ihn per Referenz oder senden Sie ihn an die Funktion insertEmployee(). Oder wählen Sie ein Synonym für die richtige Zeitformel aus: put in, load, insert; key in, type Geben Sie Folgendes ein: code, store. "Eingeschlossen" ist eine Beschreibung der Vergangenheitsform von etwas, das Ihr Code noch nicht getan hat. –

Antwort

0

Wann immer Sie wollen Eingabe parsen/Validierung nach einer Grammatik, sollten Sie einen Parser verwenden.

Schreiben Parser ist jedoch langweilig. Ziehen Sie in Betracht, einen Parser-Generator zu verwenden. Da Sie C++ schreiben, sollten Sie eine, die Sie im Fluge kompilieren, wie mit Boost-Geist:

Live On Coliru

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/qi_match.hpp> 
#include <iostream> 
#include <fstream> 

namespace qi = boost::spirit::qi; 

struct Employee { 
    unsigned id; 
    std::string firstname, surname; 
    double salary; 
    unsigned hours; 
}; 

static inline std::ostream& operator<<(std::ostream& os, Employee const& emp) { 
    return os << "Employee (" 
     << emp.id << " " 
     << emp.firstname << " " 
     << emp.surname << " " 
     << emp.salary << " " 
     << emp.hours << ")"; 
} 

struct employeeList { 
    std::vector<Employee> employees; 

    void printRoster() const { 
     std::cout << "\nRoster:\n"; 
     for (auto& emp : employees) 
      std::cout << emp << "\n"; 
    } 
}; 

namespace parser { 
    using namespace boost::spirit::qi; 
    auto const INSERT = copy(uint_ >> eol >> +graph >> eol >> +graph >> eol >> double_ >> eol >> uint_); 
} 

int main() { 
    employeeList list = employeeList(); 
    std::string line, firstName, lastName; 

    std::ifstream input("employeeFile.txt"); 
    input.unsetf(std::ios::skipws); 

    std::string command; 
    while (getline(input, command)) { 
     if (command == "INSERT_EMPLOYEE") { 
      Employee emp; 

      if (input >> qi::phrase_match(parser::INSERT, qi::blank, emp.id, emp.firstname, emp.surname, emp.salary, emp.hours)) { 
       std::cout << "Added " << emp << "\n"; 
       list.employees.push_back(emp); 
      } 
      else { 
       std::cout << "Ignoring invalid INSERT_EMPLOYEE command\n"; 
       input.clear(); 
       input.ignore(1024, '\n'); 
      } 
     } 
     if (command == "PRINT_ROSTER") { 
      list.printRoster(); 
     } 

     // skip any non-valid lines until empty line 
     while (getline(input, command)) { 
      if (command.empty()) 
       break; 
      //else std::cout << "Skipping over input '" << command << "'\n"; 
     } 
    } 
} 

Für die Eingabe gegebenen Probe druckt:

Added Employee (12345 John Smith 60000 35) 
Ignoring invalid INSERT_EMPLOYEE command 
Added Employee (34567 Michael Carter 50500 25) 

Roster: 
Employee (12345 John Smith 60000 35) 
Employee (34567 Michael Carter 50500 25) 
Verwandte Themen