2012-12-21 45 views
1

我以下列方式使用std ::函數getline():使用多種類型的行字符結束的GET線()

std::fstream verify; 
verify.open(myURI.c_str()); 
std::string countingLine; 

    if(verify.is_open()){ 

     std::getline(verify, countingLine); 

     std::istringstream iss(countingLine); 
     size_t pos; 

     // Check for the conventional myFile header. 
     pos = iss.str().find("Time,Group,Percent,Sign,Focus"); 

     if(pos == std::string::npos){//its not there 
      headerChk = false; 
      this->setStatusMessage("Invalid header for myFile file"); 
      return 0; 
     } 

     // loop that does more validation 

     iss.clear(); 

    } 

的問題是我編碼在Mac(和一些文件可以通過Windows工具和蘋果工具進行修改)。一些行尾字符是\ r而不是\ n,所以我的文件字符串永遠不會分成幾行。我相信還有第三個我應該檢查。我無法找到爲多個endOfLine字符設置delim參數的示例。

如果有人可以幫助這個例子或者一個不同的方法,那將是很棒的。 謝謝

+1

'\ r \ n'是你失蹤的人。可能有幫助:http://stackoverflow.com/questions/6864759/determining-the-newline-character-for-the-environment-ac-program-is-being-com –

+0

我依稀記得有另一個步驟,刪除'\ r '在處理混合平臺時調用'std :: getline'後。 –

+0

與問題無關但是......爲什麼你使用'iss'?另外,我懷疑你對clear()做了什麼錯誤的假設:當clear()從容器中移除元素時,它只會清除「std :: istream」的錯誤標誌。 –

回答

2

std::getline()只支持行尾字符。在文本模式下打開文件時,系統的行尾序列被轉換爲單行尾字符(\n)。但是,這不涉及其他系統的行尾字符序列。實際上,真正需要做的是從輸入中刪除\r字符。刪除字符的最佳方法可能是創建一個過濾流緩衝區。這是一個微不足道的,未經測試的,可能很慢的(不是緩衝,這意味着每個角色都有虛擬函數調用;這很可怕;但創建緩衝版本並不困難):

class normalizebuf 
    : std::streambuf { 
    std::streambuf* sbuf_; 
    char   buffer_[1]; 
public: 
    normalizebuf(std::streambuf* sbuf): sbuf_(sbuf) {} 
    int underflow() { 
     int c = this->sbuf_->sbumpc(); 
     while (c == std::char_traits<char>::to_int_type('\r')) { 
      c = this->sbuf->sbumpc(); 
     } 
     if (c != std::char_traits<char>::eof()) { 
      this->buffer_[0] = std::char_traits<char>::to_char_type(c); 
      this->setg(this->buffer_, this->buffer_, this->buffer_ + 1); 
     } 
     return c; 
}; 

你會使用此過濾器與現有的流緩衝區,是這樣的:

std::ifstream fin("foo"); 
normalizebuf sbuf(fin.rdbuf()); 
std::istream in(&sbuf); 

...然後你會使用in所有\r字符刪除讀取文件。

+1

感謝您的幫助。我在這裏發現了一個很好的帖子,展示瞭如何在http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr上創建自己的自定義getLine方法(類似於你在這裏的) -and-crlf,它涉及所有三種類型。 – Miek