2015-12-22 154 views
0

我想從txt文件中讀取信息,但有些東西沒有解決。我需要讀取每行並將其保存在屬於類Bilhete的變量中。閱讀由換行符和逗號分隔的txt文件

Alexandre 
20/12/2015 
1,2,3,4 
Luis 
30/10/1990 
3,4,5,6 

這是我的txt。

這代表票(bilhete葡萄牙): - 所有者 的名字 - expirity日期 - 我有機會獲得比賽。每個數字代表比賽的編號。在我的項目中有一個競賽類,但我不認爲這是非常重要的這個問題

void Campeonato::readFileBilhetes(string filename) { 


    ifstream ficheiro_leitura(filename.c_str()); 

    vector<Prova*> vecprovas = calendario->getProvas(); 
    vector <int> indices; //vector with competitions id 

    if(!ficheiro_leitura) 
     throw ErroNoFicheiro(filename); 
    else{ 
     string dono, data, provasNoBilhete, vendido; //owner, date, competitions in the ticket, 

     while (!ficheiro_leitura.eof()){ 

      getline(ficheiro_leitura, dono); 
      getline(ficheiro_leitura, data); 
      getline(ficheiro_leitura, provasNoBilhete); 


      stringstream dataSs; 
      date d; 
      dataSs << data; 
      int dia, mes, ano; //day, month, //year 
      char tmp; 
      dataSs >> dia >> tmp >> mes >> tmp >> ano; 

      if(dia < 1 || dia > 31|| mes < 1 || mes > 12 || ano < 1 || (dia > 28 && mes == 2) || (dia > 30 && mes == 4) || (dia > 30 && mes == 6) || (dia > 30 && mes == 9) || (dia > 30 && mes == 11)){ 
       cout << "Data invalida!"; 
      } 
      else{ 
       d.dia = dia; //day 
       d.mes = mes; //month 
       d.ano = ano; //year 
      } 



      string s1 = ""; 
      string s2= ""; 



      stringstream provasS; 
      int i = 0; 
      while (provasNoBilhete[i] != '\n' && provasNoBilhete[i] != '\0'){ 

       if(provasNoBilhete[i] == ','){ 
        int indice; 
        provasS.clear(); 
        provasS.str(""); 
        provasS.str(s2); 
        provasS >> indice; 
        indices.push_back(indice); 





       } 
       else 
        provasS << provasNoBilhete[i]; 


       ++i; 
       Bilhete *bi1 = new Bilhete(d, dono, indices); 
       inserirBilhete(*bi1); //insert 
      } 


     } 
    } 

} 

如何正確保存這些值?

問候

+1

你能澄清你遇到的問題嗎? – badfilms

+0

[你不應該使用while(!ifstream.eof()'。](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong),這可能是你問題的根源。 – Beta

回答

0

我不知道在你的文件中讀取當你有問題,但這裏是展示瞭如何在你試圖獲取值的示例讀取什麼值。這將在名稱中正確讀入字符串,將日期寫入單獨的整數,並將競爭ID寫入整數向量中。我發現使用iss.peek方法對調試stringstream非常有幫助。在這裏,您可以看到我正在使用此方法來確保我正在讀取有效文件。

此外,正如Beta所言,我會建議不要使用file.eof()。在條件循環中嘗試使用getline

fstream infile(file); 
string linha, dono; 
int dia, mes, ano; 
vector<int> campeonatoIds; 

while (getline(infile, dono)) // get name and check status file stream 
{ 
    cout << dono << endl; 
    // read in date 
    getline(infile, linha); 
    int tmp; 
    istringstream iss (linha); 
    iss >> dia; 
    if (iss.peek() != '/') 
    { 
     cerr << "incorrectly formatted file" << endl; 
     exit(EXIT_FAILURE); 
    } 
    iss.ignore(); 
    iss >> mes; 
    if (iss.peek() != '/') 
    { 
     cerr << "incorrectly formatted file" << endl; 
     exit(EXIT_FAILURE); 
    } 
    iss.ignore(); 
    iss >> ano; 


    cout << dia << "/" << mes << "/" << ano << endl; 

    // read in competition ids 
    getline(infile, linha); 
    istringstream iss2(linha); 
    while (iss2.peek() != ',' && iss2.good()) 
    { 
     iss2 >> tmp; 
     cout << tmp << ","; 
     campeonatoIds.push_back(tmp); 
     iss2.ignore(); 
    } 
    cout << endl; 
} 

然而,我個人的事情,使用getline比在這種情況下使用stringstream更容易和更清潔。以下是使用getline重構的相同代碼。

fstream infile(file); 
string linha, dono; 
int dia, mes, ano; 
vector<int> campeonatoIds; 

while (getline(infile, dono)) // get name and check status file stream 
{ 
    cout << dono << endl; 
    // read in date 
    getline(infile, linha); 
    istringstream iss (linha); 
    string tmpstr1; 
    getline(iss, tmpstr1, '/'); 
    dia = atoi(tmpstr1.c_str()); 

    getline(iss, tmpstr1, '/'); 
    mes = atoi(tmpstr1.c_str()); 

    getline(iss, tmpstr1, '/'); 
    ano = atoi(tmpstr1.c_str()); 

    cout << dia << "/" << mes << "/" << ano << endl; 

    // read in competition ids 
    getline(infile, linha); 
    istringstream iss2(linha); 
    string tmpstr2; 
    while (getline(iss2, tmpstr2, ',')) 
    { 
     campeonatoIds.push_back(atoi(tmpstr2.c_str())); 
    } 

    for (auto it : campeonatoIds) 
    { 
     cout << it << ",";  
    } 
    cout << endl; 
    campeonatoIds.clear(); 
} 

正如你所看到的,我在沒有while循環,它可以讓你檢查文件的有效性,使用getline。另外,我認爲使用getline可以讓你提供一個可選的分隔符來簡單分離文件流。

0

我會從operator>>中爲ticket類重載012,因此它有正文讀取單個票據。然後,我會使用該運算符從流中讀取票據。

該標準已定義了get_tgime(和put_time)機械手來讀取流的時間爲struct tm,所以我們還不如用這些。

代碼可能是這個樣子:

friend std::istream &operator>>(std::istream &is, ticket &t) { 
    std::getline(is, t.name); 

    is >> std::get_time(&t.date, " %d/%m/%Y "); 

    std::string temp; 
    std::getline(is, temp); 

    t.events = parse_list<int>(temp); 
    return is; 
} 

parse_list會是這樣這一般順序:

template <class T> 
std::vector<T> parse_list(std::string const &in) { 
    T temp; 
    std::vector<T> ret; 

    std::istringstream buf(in); 

    while (buf >> temp) { 
     ret.push_back(temp); 
     buf.ignore(1); 
    } 
    return ret; 
} 

有了這些規定,讀滿ticket數據的文件,並把它所有成vector看起來像這樣:

std::vector<ticket> tickets { std::istream_iterator<ticket>(input), 
    std::istream_iterator<ticket>() }; 
相關問題