2014-12-01 19 views
1

我正試圖從C++ 98中的文本文件中讀取數據。它有一個模式,但有時一個字段爲空:從C++中讀取文件,處理空白

ID Name Grade level 
1 a 80 A 
2 b B 
3 c 90 A 

如何從文件中讀取,這樣我可以忽略的空白? (我希望我可以簡單地使用正則表達式:\ d *)

有沒有簡單的方法來做到這一點?

+0

這些字段是否保證爲固定寬度? – sfjac 2014-12-01 23:25:53

+0

如果你想把它們當作字符串,不!他們可以是小號或大號 – 2014-12-01 23:26:55

+0

然後你怎麼知道第2行缺少哪個字段?字段總是由一個空格分隔嗎? – sfjac 2014-12-01 23:29:16

回答

1

您需要使用關於輸入的知識來對缺失的內容進行假設。您可以使用std::stringstream解析文本行中的單個術語。換句話說,std::stringstream通過忽略空格並僅獲得完整的項來處理空​​白,例如std::stringstream("aaa bbb") >> a >> b將加載字符串a"aaa"b"bbb"

下面是一個例子程序,分析輸入,使一個從無到有的健壯的分析器是很困難的,但如果你輸入的是嚴格的,你確切地知道什麼樣的期待,那麼你可以用一些簡單的代碼就完事:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <sstream> 

//----------------------------------------------------------------------------- 
// holds a data entry 
struct Entry { 
    int id; 
    std::string name; 
    int grade; 
    std::string level; 

    Entry() { 
     // default values, if they are missing. 
     id = 0; 
     name = "Unknown"; 
     grade = 0; 
     level = "?"; 
    } 

    void ParseFromStream(std::stringstream &line) { 

     std::string s; 
     line >> s; 

     if(s[0] >= '0' && s[0] <= '9') { 
      // a number, this is the ID. 
      id = atoi(s.c_str()); 

      // get next term 
      if(line.eof()) return; 
      line >> s; 
     } 

     if(s[0] >= 'a' && s[0] <= 'z' || s[0] >= 'A' && s[0] <= 'Z') { 
      // a letter, this is the name 
      name = s; 

      // get next term 
      if(line.eof()) return; 
      line >> s; 
     } 

     if(s[0] >= '0' && s[0] <= '9') { 
      // a number, this is the grade 
      grade = atoi(s.c_str()); 

      // get next term 
      if(line.eof()) return; 
      line >> s; 
     } 

     // last term, must be level 
     level = s; 
    } 
}; 

//----------------------------------------------------------------------------- 
int main(void) 
{ 
    std::ifstream input("test.txt"); 

    std::string line; 
    std::getline(input, line); // (ignore text header) 

    while(!input.eof()) { 
     Entry entry; 

     std::getline(input, line); // skip header 
     if(line == "") continue; // skip empty lines. 

     entry.ParseFromStream(std::stringstream(line)); 

     std::cout << entry.id << ' ' << entry.name << ' ' << 
        entry.grade << ' ' << entry.level << std::endl; 

    } 

    return 0; 
}