2016-05-06 3 views
1

Das ist mein struct:Wie importiere ich Daten aus einer Datei in mein Array von struct?

struct Event{ 
    int day; 
    int month; 
    int year; 
    int weekday; 
    string event; 
}; 

wie Meine Ereignisse Datendatei sein würde:

# Comment and empty lines are ignored 
# ’$’ means LAST, ’*’ is wildcard 
# Weekday on symbolic from Mon,Tue,Wed,Thu,Fri,Sat,Sun 
# Events specs start 
# Last day is payday 
$.*.*:*:Payday 
# Birthday at 1.3 
1.3.*:*:Birthday Party 
# Darts on Fridays 
*.*.*:Fri:Darts evening 
13.*.*:Fri:Friday the 13th 
# EOF 

Ich habe versucht, diese Funktion zu schreiben:

void readFile(vector<string> &data){ 
    string line; 
    ifstream readFile("events.dat", ios::in); 
    if (!readFile) { 
     cerr<<"File COuld not be opened"<<endl; 
     exit(EXIT_FAILURE); 
    } 
    while (readFile && !readFile.eof()) { 
      getline(readFile,line); 
      if (line.length() == 0 or line[0] == '#' or line[0] == '/') 
       break; 
      data.push_back(line); 
     } 
    } 

ich aber jetzt nicht wissen, wie man Datenvektor in Ereignisvektor umwandelt?

+0

Sie könnten lesen wollen [ „? Warum ist Iostream :: EOF innerhalb einer Schleife Bedingung falsch als“] (http : //stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-sidered-wrong). –

+0

Sie könnten auch daran interessiert sein, mehr abouit ['std :: getline'] (http://en.cppreference.com/w/cpp/string/basic_string/getline) zu lesen, da es zum Analysieren der Zeilen verwendet werden könnte, die Sie haben . Ich empfehle Ihnen auch, über ['std :: stoi'] (http://en.cppreference.com/w/cpp/string/basic_string/stol) nachzulesen. –

Antwort

0

Sie könnten es mit std::istringstream und std::getline tun, es hat einen dritten Parameter, der eine char ist, bei der es aufhören sollte, Zeichen zu verbrauchen und String zurückzugeben. Andere Vorgehensweise ist die Verwendung von Regexps, unten ist ein Weg, wie Sie es mit Regexps parsen können, ich habe es mit nur einer Zeichenfolge getestet, aber es sollte Ihnen einen Anfang geben, wie es geht.

http://coliru.stacked-crooked.com/a/d3aed577b2f72bd7

#include <iostream> 
#include <string> 
#include <regex> 

struct Event{ 
    int day; 
    int month; 
    int year; 
    int weekday; 
    std::string event; 
}; 

int main() 
{ 
    std::regex pattern("([0-9\\$\\*]+)\\.([0-9\\$\\*]+)\\.([0-9\\$\\*]+):(\\w+):([\\w ]+)"); 
    std::string line = "13.*.*:Fri:Friday the 13th"; 
    std::smatch sm; 
    Event evt; 
    if (std::regex_match(line, sm, pattern)) { 
     std::string val1 = sm[1]; 
     if (val1 == "*") 
      evt.day = -1; // wildcard 
     else if (val1 == "$") 
      evt.day = -2; // last 
     else 
      evt.day = std::stoi(val1); 

     val1 = sm[2]; 
     if (val1 == "*") 
      evt.month = -1; // wildcard 
     else if (val1 == "$") 
      evt.month = -2; // last 
     else 
      evt.month = std::stoi(val1); 

     val1 = sm[3]; 
     if (val1 == "*") 
      evt.year = -1; // wildcard 
     else if (val1 == "$") 
      evt.year = -2; // last 
     else 
      evt.year = std::stoi(val1); 


     std::string weekDay = sm[4]; 
     std::vector<std::string> weekdays = {"Mon", "Tue", "Wen", "Thr", "Fri", "Sat", "Sun"}; 
     auto it = std::find(weekdays.begin(), weekdays.end(), weekDay); 
     evt.weekday = std::distance(weekdays.begin(), it); 

     evt.event = sm[5]; 

     std::cout << evt.day << ", " << evt.month << ", " << evt.year << ", " << evt.weekday << ", " << evt.event << "\n";  
    } 
} 

auf Ausgang:

13, -1, -1, 4, Friday the 13th 
0
#include <iomanip> 
#include <iostream> 
#include <string> 
#include <fstream> 
#include <iomanip> 
#include <cstdlib> 
#include <vector> 
using namespace std; 

string Day[7] = {"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 

// define struct Date to collect information for Date 
struct Date { 
    int day;    // variable to collect day 
    int month;    // variable to collect month 
    int year;    // variable to collect year 
    int weekday;   // variable to store weekday value 
    string event;   // string to hold events 
    int last; 

}; 
struct Event{ 
    int day; 
    int month; 
    int year; 
    int weekday; 
    string event; 
}; 
vector<Event> myhappening; 
vector<string> data; 

void inputDate(Date &);  // prototype of inputDate function 
void checkYear(Date &);  // prototype of checkYear function 
void checkMonth(Date &); // prototype of checkMonth function 
void checkDay(Date &);  // prototype of checkDay function 
void checkLast(Date &);  // prototype of checkLast function 
void increment(Date &);  // prototype of increment function 
void setWeekDay(Date &); // prototype of setWeekDay function 
void setEvent(Date &,Event []);  // prototype of setEvent function 
void outputDate(Date &); // prototype of outputDate function 
void setFirstWeekDay(Date &); // set weekday to the first day of the week 
void decrement(Date &date); // Prototype of decrement function 
void readFile(vector<string> &); 


// main function 
int main() 
{ 
    Date time;       // intialiaze our struct 
    inputDate(time);     // Ask from user to input a date 
    Event MyHappenings[] = 
    { 
     { -1, 0, 0, 0, "Payday" }, 
     { 1, 3, 0, 0, "Birthday Party" }, 
     { 0, 0, 0, 5, "Darts evening" }, 
     {13, 0, 0, 5, "Friday the 13th" }, 
     // {2,3,0,0,"Hooooraaa another event"}, // You can add other events too here," no limits " 
    };         // Initialize the events, 
    setWeekDay(time); 
    setFirstWeekDay(time); 
    for (int i = 0; i < 7; i++) 
    { 
     setWeekDay(time);    // Calculate the weekday of a date 
     checkLast(time);    // check that if a date is the last date of the month or not 
     setEvent(time,MyHappenings); // compare the date and events, and set events related to that date 
     outputDate(time);    // print date with weekdays and events 
     increment(time);    // increment a date by one day 
    } 
    readFile(data); 
     }// end of main function 

// inputDate function to get date from user and store it in Date struct 
void inputDate(Date &date) 
{ 

    cout<<" Enter Your Date (Year starts from 1754) and Follow this format by space DD MM YYYY :"<<endl; 
    cin>>date.day>>date.month>>date.year; 
    checkYear(date); 
    checkMonth(date); 
    checkDay(date); 
    cout<< " Your Given Date is : "<<date.day<<" "<<date.month<<" "<<date.year<<endl; 
}// end function inputDate 

// checkYear Function to check year value to be correct and ask user for correct value if it is uncorrect 
void checkYear(Date &date) 
{ 
    while (date.year<1754 or date.year>9999) { 
     cout<< " You pick wrong Year!(It should be between 1754 and 9999)Please Enter new Year Value : "; 
     cin>>date.year; 
    } 
}// End checkYear function 

// checkMonth Function to check month value to be correct and ask user for correct value if it is uncorrect 
void checkMonth(Date &date) 
{ 
    while (date.month>12 or date.month<1) { 
     cout<< " You pick wrong Month!(You should pick months between 1-12) Please Enter new Month Value : "; 
     cin>>date.month; 
    } 
}//End function checkMonth 

//checkDay Function to check day value to be correct and ask user for correct value if it is uncorrect 
void checkDay(Date &date) 
{ 
    switch (date.month) { 
     case 1: case 3: case 5: case 7: case 8: case 10: case 12 : 
      while (date.day>31 or date.day<1) { 
       cout<< " You pick wrong Day!(It should be in 1- 31 range) Please Enter new Day Value : "; 
       cin>>date.day; 
      } 
      break; 
     case 4: case 6: case 9: case 11: 
      while (date.day>30 or date.day<1) { 
       cout<< " You pick wrong Day!(It should be in 1- 30 range) Please Enter new Day Value : "; 
       cin>>date.day; 
      } 
      break; 
     case 2 : 
      if ((date.year % 4 ==0 and date.year%100 !=0) or date.year%400==0 ){ 
       if (date.day>29 or date.day<1) { 
        cout<< " You pick wrong Day!(It should be in 1- 29 range) Please Enter new Day Value : "; 
        cin>>date.day; 
       } 
      }else{ 
       while (date.day>28 or date.day<1) { 
        cout<< " You pick wrong Day!(It should be in 1- 28 range) Please Enter new Day Value : "; 
        cin>>date.day; 
       } 
      } 
      break; 

     default: 
      cout<<" The program should not get into this code"<<endl; 
      break; 
    } 
}// End checkDay function 

// checkLast funtion to find if a date is last day of the month or not 
void checkLast(Date &date) 
{ 
    date.last = 0; 
    switch (date.month) { 
     case 1: case 3: case 5: case 7: case 8: case 10: case 12 : 
      if (date.day ==31) 
       date.last=-1; 
      break; 
     case 4: case 6: case 9: case 11: 
      if (date.day ==30) 
       date.last=-1; 
      break; 
     case 2 : 
      if ((date.year % 4 ==0 and date.year%100 !=0) or date.year%400==0 ){ 
       if (date.day ==29) 
        date.last=-1; 
      }else{ 
       if (date.day ==28) 
        date.last=-1; 
      } 
      break; 

     default: 
      cout<<" The program should not get into this code"<<endl; 
      break; 
    } 
}// End checkLast function 

// increment Function to calculate increment days respect to the user input 
void increment(Date &date) 
{ 
    date.day= date.day + 1; 
    switch (date.month) { 
     case 1: case 3: case 5: case 7: case 8: case 10: 
      if (date.day > 31) 
      { 
       date.month++; 
       date.day= date.day- 31; 
      } 
      break; 

     case 4: case 6: case 9: case 11: 
      if (date.day > 30) 
      { 
       date.month++; 
       date.day= date.day- 30; 
      } 
      break; 

     case 2: 
      if ((date.year % 4 ==0 and date.year%100 !=0) or date.year%400==0 ){ 
       if (date.day > 29){ 
        date.month++; 
        date.day = date.day - 29; 
       } 
      }else { 
       if (date.day > 28){ 
        date.month++; 
        date.day = date.day - 28; 
       } 
      } 
      break; 

     case 12 : 
      if (date.day > 31) 
      { 
       date.month = date.month - 11;; 
       date.year++; 
       date.day = date.day - 31; 
      } 
      break; 

     default: 
      cout<<"Program should not get into this error in increment Function!!!"<<endl; 
      break; 
    } 
} // end increment Function 

//setWeekDay function to calculate weekday 
void setWeekDay(Date &date){ 
    // find the algorithm here "https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week" 
    int a = (14-date.month)/12; 
    int y = date.year-a; 
    int m = date.month+12*a-2; 
    date.weekday = (date.day + y + y/4 - y/100 + y/400 +(31 * m/12)) % 7; 
}// end setWeekDay function 

//setEvent function to set events related to their related events 
void setEvent(Date &date,Event event[]){ 
    date.event = "-"; 
    string a; 
    for(int i=0 ; i<sizeof(event); i++){ 
     if((date.day==event[i].day or event[i].day == 0 or event[i].day == date.last) and (date.month==event[i].month or event[i].month == 0) and (date.year==event[i].year or event[i].year == 0) and (date.weekday==event[i].weekday or event[i].weekday == 0)){ 
      if(a.empty()){ 
       date.event = event[i].event; 
       a = date.event; 
       continue; 
      }else{ 
       date.event = event[i].event+","+ a; 
       a = date.event; 
       continue; 
      } 
     } 
    } 
} // end of setEvent function 

// outputDate function which use increment function to increment a date and also set event related to input date 
void outputDate(Date &date) 
{ 
    cout<<setfill('0'); 
    cout<<setw(2)<<date.day<<"."<<setw(2)<<date.month<<"."<<setw(4)<<date.year<<"  "<<"[ "<<Day[date.weekday]<<" ]"<<"  "<<date.event<<endl; 
} // end of outputDate function 

//setFirstWeekDay Function to find first day of the week related to given date 
void setFirstWeekDay(Date &date){ 
    switch (date.weekday) { 
     case 0: 
      for (int i = 1; i<7; i++) 
       decrement(date); 

      //date.day = date.day - 6; 
      break; 
     case 2: 
      decrement(date); 
      break; 
     case 3: 
      for (int i = 1; i<3; i++) 
       decrement(date); 
      break; 
     case 4: 
      for (int i = 1; i<4; i++) 
       decrement(date); 
      break; 
     case 5: 
      for (int i = 1; i<5; i++) 
       decrement(date); 
      break; 
     case 6: 
      for (int i = 1; i<6; i++) 
       decrement(date); 
      break; 

     default: 
      break; 
    } 
}// end setFirstWeekDay Function 
// Decrement Function to decrement days by one day 
void decrement(Date &date) 
{ 
    date.day= date.day - 1; 
    switch (date.month) { 
     case 12: case 5: case 7: case 8: case 10: 
      if (date.day == 0) 
      { 
       date.month--; 
       date.day= 30; 
      } 
      break; 

     case 2: case 4: case 6: case 9: case 11: 
      if (date.day == 0) 
      { 
       date.month--; 
       date.day= 31; 
      } 
      break; 

     case 3: 
      if ((date.year % 4 ==0 and date.year%100 !=0) or date.year%400==0 ){ 
       if (date.day == 0){ 
        date.month--; 
        date.day = 29; 
       } 
      }else { 
       if (date.day == 0){ 
        date.month--; 
        date.day = 28; 
       } 
      } 
      break; 

     case 1 : 
      if (date.day == 0) 
      { 
       date.month = date.month + 11;; 
       date.year--; 
       date.day = 31; 
      } 
      break; 

     default: 
      cout<<"Program should not get into this error in increment Function!!!"<<endl; 
      break; 
    } 
} // end decrement Function 
void readFile(vector<string> &data){ 
    string line; 
    ifstream readFile("events.dat", ios::in); 
    if (!readFile) { 
     cerr<<"File COuld not be opened"<<endl; 
     exit(EXIT_FAILURE); 
    } 
    while (readFile && !readFile.eof()) { 
     getline(readFile,line); 
     //if (line.length() == 0 or line[0] == '#') 
     data.push_back(line); 
    } 
    for(int i=0; i < data.size(); i++){ 
     cout<<data[i]; 
    } 

} 

dies ist, wie ich bis jetzt getan haben, nach, dass ich auf Ereignisvektor myhappening setzen Daten wollen. Vorher würde ich sehen, ich benutze normale Event-Struktur, um ein Array zu initialisieren, aber jetzt möchte ich Dateiverarbeitung verwenden.

0

Die Schwierigkeit besteht darin, dass Ihre Ereignisstruktur int verwendet und Ihr Format spezielle Zeichen akzeptiert. Wenn Sie annehmen, dass * in 0 und die $ in -1 übersetzt werden, können Sie die folgende Funktion verwenden:

Event string_to_event (string s) { 
    static vector<string> wd{"*","Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; 
    stringstream sst(s); 
    Event e; 

    string sday,smonth,syear,sweekday; 
    getline(getline (getline (getline(getline(sst,sday,'.'), smonth,'.'), syear,':'), sweekday, ':'), e.event); 

    e.day = sday.compare("*")==0 ? 0: (sday.compare("$")==0 ? -1 : stoi(sday)); 
    e.month = smonth.compare("*")==0 ? 0: (smonth.compare("$")==0 ? -1 : stoi(smonth)); 
    e.year = syear.compare("*")==0 ? 0: (syear.compare("$")==0 ? -1 : stoi(syear)); 

    e.weekday = find(wd.begin(), wd.end(), sweekday)-wd.begin(); 

    return e; 
} 

Wie Sie sehen es extensiven Einsatz von stringstreams und getline() macht.

Wenn Sie Ihren Vermittler Datenvektor loswerden können, coud Sie readLine() wie folgt umschreiben:

void readFile(vector<Event> &data){ 
    string line; 
    ifstream readFile("events.dat", ios::in); 
    if (!readFile) { 
     cerr<<"File COuld not be opened"<<endl; 
     exit(EXIT_FAILURE); 
    } 
    while (getline(readFile,line)) { 
     if (line.length() != 0 && line[0] != '#' && line[0] != '/') { 
      data.push_back(string_to_event(line)); 
     } 
    } 
} 

Wenn Sie Ihre Zwischenstruktur halten müssen, sollten Sie Ihre ursprüngliche Lesefunktion korrigieren, durch Looping auf getline() und nicht auf eof() und verwenden Sie continue anstelle von break.

Sie könnten dann tranform() verwenden, um die converstion Funktion auf dem Vektor von Zeichenketten anwenden:

vector<string> vs; 
vector<Event> evt; 
readFile(vs); 
transform (vs.begin(), vs.end(), back_inserter(evt), string_to_event); 
copy (evt.begin(), evt.end(), ostream_iterator<Event>(cout,"\n")); 
Verwandte Themen