简体   繁体   中英

C++ reading from a file

I have a file that is organized into columns, with data that needs to be stored in a vector of a type of class to store each of the data columns, I would suppose.

The data looks like:

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

There are also some redundant columns in the beginning that I do not want, how can I select data as needed. Can someone direct me in the correct direction?

Just read the data in, and ignore the values you don't care about:

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
}

If you want to make sure you're only reading data from a single line, first use getline to put the line into a string, then use an istringstream as your input stream. You need to have a way to differentiate valid data lines from non data lines. Is it safe to assume that every valid data line begins with "ATOM", and also that every line that begins with "ATOM" is in fact a valid data line? If so, you can use that to determine if the line is data:

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
        }
    }
}

On second thoughts: If you're looking for a simple solution for a homework assignment, the following isn't it, but...

I hate doing anything but the most trivial I/O using C++ iostreams, or even using the C scanf-family functions. It's usually not too hard to get the basics running, but I'd have to look up the details again. And in any case, the resulting code tends to be very fragile if you get badly formatted inputs.

In my opinion, for a job like this, you should use a tool like Ragel .

For a purely C++ solution, though, I'd recommend...

  1. Read the input in a line at a time using the getline method.
  2. Interpret the line using the regular expression tools that are available in Boost, TR1 and in C++11. There's a tutorial here , though I've only looked at it briefly.

As regex is officially part of C++ as of C++11, and as an implementation has been available from Boost for a while, most up-to-date compilers should support this by now - and you can always use the Boost version otherwise.

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.

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