繁体   English   中英

将文本文件中的行解析为存储在包含不同数据类型的类数组中的变量

[英]Parsing lines from a text file to variables which are stored in an array of class containing different data types

我正在用 C++ 编写一个程序,我想用它来读取和解析 (.pdb) 文本文件中的行。 文本文件包含由以下三行组成的各种标题:

COMPND     MFI
AUTHOR     GENERATED BY IRASPA
CRYST1    20.090   19.738   13.142  90.00 9 90.00 90.00 P  1          1

之后的行包含有关化合物特定原子的信息,如下所示:

ATOM # CHAR 0 FLOAT1 FLOAT2 FLOAT3 1.00 0.00 CHAR

其中 # 是一个整数(原子数),CHAR 是原子符号(在这种情况下是 O 或 Si)。 FLOAT 分别是 x、y 和 z 坐标。

前四行是:

ATOM      1  O          0      0.024  8.489  10.490  1.00  0.00        O
ATOM      2  O          0     10.069  1.380  9.223   1.00  0.00        O
ATOM      3  O          0     20.066  11.249 2.652   1.00  0.00        O
ATOM      4  O          0     10.069  8.489  9.223   1.00  0.00        O

到目前为止,我已经设法逐行阅读文本并使用sscanf扫描内容。 但是,我无法将数据存储到我创建的 Atom class的数组中。 这是包含在我的头文件中的类的外观:

class Atom  {
public:
        Atom()
        {};'

        int atom_num;
        char atom_sym[2];
        float atom_x, atom_y, atom_z;
};

到目前为止,这是我的程序:

int main()
{
    int i;
    int Linecount = 0;
    Atom atomList[i];

    char ign_a, ign_t, ign_o, ign_m; // I use these to store the ATOM of each line
    int ign1;  // I use this to store the 0 that appears before the coordinates of each line

    std::string filename = "textfile.pdb"
    std::ifstream file;

    file.open (filename.c_str()); // I use this section to get the total number of lines to be parsed
    if (!file)  {
        cout << "Error opening file.";
        return -1;
    }
    if (file.is_open())  {
        std::string line;
        while (getLine(file, line))
            ++Linecount;
    }
    file.close();

    file.open (filename.c_str());
    if (file.is_open())  {
        std::string line;
        int atom_num;
        char atom_sym[2];
        float atom_x, atom_y, atom_z;
        for (i = 1; i < Linecount; ++i)  { // I have tried this for loop in different sections of the program but nothing seems to work
            while (getline(file, line))  {
                if (line.find("ATOM") == 0)  {
                    sscanf(line.c_str(), "%c%c%c%c %d %s %d %f %f %f", &ign_a, &ign_t, &ign_o, &ign_m,
                            &atom_num, atom_sym, &ign1, &atom_x, &atom_y, &atom_z); //

                    atomList[i].atom_num = atom_num; // This is where I attempt to store the data into the array
                    strcpy(atomList[i].atom_sym, atom_sym);
                    atomList[i].atom_x = atom_x;
                    atomList[i].atom_y = atom_y;
                    atomList[i].atom_z = atom_z;
                }

                    printf("%d %s %.3f %.3f %.3f\n", atomList[i].atom_num, atomList[i].atom_sym,
                            atomList[i].atom_x, atomList[i].atom_y, atomList[i].atom_z); // Test reading of lines
            }
    }
    file.close();

    int j = 10;
    printf("TEST: %d %s %.3f %.3f %.3f\n", atomList[j].atom_num, atomList[j].atom_sym,
            atomList[j].atom_x, atomList[j].atom_y, atomList[j].atom_z);  // Print function to test storing into array

return 0;
}

尽管使用if (line.find("ATOM") == 0)语句,但第一个打印函数似乎可以正常工作,尽管它打印了三个“垃圾”行,我认为这是由于文本文件的标题造成的。 这是输出:

0 0.000 0.000 0.000
0 0.000 0.000 0.000
0 0.000 0.000 0.000
1 O 0.024 8.489 10.490
2 O 10.069 1.380 9.223
3 O 20.066 11.249 2.652
4 O 10.069 8.489 9.223

但是,第二个打印函数仅打印零值,这表明数据没有正确存储到数组中。 我也尝试过使用std::cinstd::cout来分配和打印数据,但这似乎没有帮助。 这是第二个打印函数的输出:

TEST: 0 0.000 0.000 0.000

我的主要问题是我无法将输入文件中的数据存储到 Atom 类的数组 atomList[i] 中。

我将不胜感激。 谢谢!

不确定这是否会回答您的任何问题,但这是一种方法。 它不使用任何旧的 C 类型习语,如scanf和原始数组。

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

// Overloaded extraction operator
std::ifstream& operator>>(std::istream& i, Atom& a)
{
    std::string temp;
    int temp2;

    if (i >> temp
          >> a.atom_num
          >> a.atom_sym
          >> temp2
          >> a.atom_x
          >> a.atom_y
          >> a.atom_z) {
        i.ignore(256, '\n'); // Discard rest
    }

    return i;
}
// Overloaded insertion operator
std::ofstream& operator<<(std::ostream& o, const Atom& a)
{
    o << a.atom_num << " "
      << a.atom_sym << " "
      << std::setprecision(3) << a.atom_x << " "
      << std::setprecision(3) << a.atom_y << " "
      << std::setprecision(3) << a.atom_z;

    return o;
}

int main()
{
    std::string filename = "textfile.pdb";
    std::ifstream file(filename);

    std::vector<Atom> atomList;

    if (file) {
        std::string line;
        while (std::getline(file, line)) {
            if (line.find("ATOM") == 0) {
                std::stringstream ss(line);
                Atom temp;
                if (ss >> temp) {
                    atomList.push_back(temp);
                }
            }
        }
    }

    if (atomList.size() > 10) {
        std::cout << atomList[10] << '\n';
    }

    return 0;
}



Answered by Johhny Mopp in my question repost.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM