I am writing a program in C++ with which I want to read and parse lines from a (.pdb) text file. The lines look like this:
ATOM # CHAR 0 FLOAT1 FLOAT2 FLOAT3 1.00 0.00 CHAR
Where # is an integer (the atom number) and CHAR is the atom symbol (in this case either O or Si). The FLOATs are x, y, and z coordinates respectively.
The first three lines are:
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
So far I've managed to read the text line by line and scan the contents using sscanf
. However, I'm unable store the data into an array of the Atom class
that I've created. Here's what the class looks like which is included in my header file:
class Atom {
public:
Atom()
{};'
int atom_num;
char atom_sym[2];
float atom_x, atom_y, atom_z;
};
Here's the section of my program where I parse the lines:
int main()
{
int i;
int Linecount = 0;
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());
if (file.is_open()) {
std::string line;
while (getline(file, line))
++Linecount;
}
file.close();
Atom atomList[Linecount];
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 parsing 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;
}
The first print function appears to work correctly although it prints three "garbage" lines which I assume are due to the header of the text file despite using the if (line.find("ATOM") == 0)
statement. Here's the output up to the third line:
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
The second print function, however, prints zero values only which indicates that the data is not being stored into the array correctly. I have also tried using std::cin
and std::cout
for assigning and printing the data but that did not appear to help. Here's the output for the second print function:
TEST: 0 0.000 0.000 0.000
My main issue here is that I'm unable to store the data from the input file into the array atomList[i] of class Atom. I've tried moving the for loop around as well as scanning directly into the atomList[i] variables among other things but I'm stuck at this point. What would I need to change so that the lines are read one by one and the correct information stored into the array?
I would appreciate any help with this. Thanks!
Not sure if this will answer any of your questions, but here's a way to do it. It doesn't use any of the old C-type idioms like scanf
and raw arrays.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <string>
#include <sstream>
// Overloaded extraction operator
std::istream& 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::ostream& 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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.