2011-11-20 96 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版本。