2011-11-20 93 views
3

我有一個文件組織成列,其中的數據需要存儲在一個類的類型的向量中以存儲每個數據列,我想。從文件中讀取的C++

的數據是這樣的:

ATOM  1 N PRO  1  -38.396 -1.525 2.011 -0.18 14.01 
ATOM  2 CA PRO  1  -36.931 -1.372 2.090 0.08 13.02 
ATOM  3 C PRO  1  -36.353 -0.411 1.059 0.35 12.01 
ATOM  4 O PRO  1  -36.988 -0.061 0.086 -0.37 16.00 
ATOM  5 CB PRO  1  -36.368 -2.749 1.735 0.03 14.03 
ATOM  6 CG PRO  1  -37.417 -3.202 0.763 0.01 14.03 
ATOM  7 CD PRO  1  -38.692 -2.893 1.489 0.08 14.03 

也有,我不想一開始,我怎麼可以根據需要選擇一些數據冗餘列。 有人能指引我正確的方向嗎?

+1

所以基本上你正在尋找一個不錯的方法來分割分隔字符串? – GWW

+2

是的,但是在數據中還存在這樣的其他問題,即文件中的數據也不統一,有幾行空白行和其他行中沒有用到的文本。 – freshmaster

回答

3

剛剛讀入數據,而忽視了價值,你不關心:

std::string c1, c3, c4; 
int c2, c5; 
double c6, c7, c8, c9, c10; 

if (!(input_stream >> c1 >> c2 >> c3 >> c4 >> c5 >> c6 >> c7 >> c8 >> c9 >> c10)) 
{ 
    // error 
} 

如果你想確保你只從單一的線,第一次使用函數getline讀取數據放將該行轉換爲字符串,然後使用istringstream作爲輸入流。您需要有一種方法來區分有效的數據線和非數據線。假設每條有效的數據行都以「ATOM」開頭,並且以「ATOM」開頭的每一行實際上都是有效的數據行是否安全?如果是這樣,你可以用它來確定該行的數據:

for (std::string line; std::getline(file_stream, line);) 
{ 
    std::string c1, c3, c4; 
    int c2, c5; 
    double c6, c7, c8, c9, c10; 

    std::istringstream iss(line); 

    iss >> c1; 
    if (c1 == "ATOM") 
    { 
     if (!(iss >> c2 >> c3 >> c4 >> c5 >> c6 >> c7 >> c8 >> c9 >> c10)) 
     { 
      // error 
     } 
    } 
} 
+1

是的,這有幫助。如果數據中間有一些冗餘行或者空白或者有像評論這樣的文本,我該怎麼辦? – freshmaster

+0

@freshmaster:查看更新後的答案。 –

1

關於第二個想法:如果你正在尋找一個家庭作業一個簡單的解決方案,下面是不是,而是...

我討厭做任何事情,除了使用C++ iostreams的最微不足道的I/O,或者甚至使用C scanf-family函數。基本運行通常不會太難,但我必須再次查看細節。在任何情況下,如果得到格式不正確的輸入,結果代碼往往非常脆弱。

在我看來,對於這樣的工作,你應該使用像Ragel這樣的工具。

對於一個純粹的C++的解決方案,不過,我建議......

  1. 使用getline方法一次讀入一行輸入。
  2. 使用Boost,TR1和C++ 11中提供的正則表達式工具解釋該行。有一個教程here,雖然我只是簡單地看了一下。

由於regex是正式的C++作爲C++ 11的一部分,作爲實現已經可以從加速了一段時間,最先進的最新編譯器現在應該支持這一點 - 你可以隨時否則使用Boost版本。