Hello all,

I have a text file called: concentrations.dat

The file contains a lot of different data. Here's the data that I'm interested in:

# ET: list of elements
<ET>
'Cu' 'C' 'Sr' 'He' 'Mg' 'O' 'Cr'

What I want to do is read the elements into a vector called elementVector. So I would end up with Cu, C, Sr, He, Mg, O, and Cr as elements of the vector without the ' symbols.

Can anyone tell me how to do this? An example would be much appreciated. I have had no success with using ifstream. I can read in an entire file, but I can get parts of it out!

I could either read in the entire file or only read in the part that I wrote above. Then I would need to get the elements, while discarding the ' symbols.

I need to do this because I have written a program for doing calculations that needs to know which chemical elements are involved.

Thanks for any help.

Dani AI

Generated

’s idea—scan to the ET marker, then parse the following text—is the right direction. A slightly more robust approach is to locate the marker case‑insensitively, then use a regex to capture tokens enclosed in single or double quotes. The snippet below extracts symbol tokens (1–3 letters) into a vector and preserves original capitalization; it is an alternative to the line-by-line tokenization shown earlier.

#include <fstream>
#include <string>
#include <vector>
#include <regex>
#include <algorithm>
#include <cctype>
#include <iterator>

std::vector<std::string> extractElements(const std::string& filename)
{
    std::ifstream in(filename);
    if (!in) return {};

    std::string content((std::istreambuf_iterator<char>(in)),
                        std::istreambuf_iterator<char>());

    std::string lower = content;
    std::transform(lower.begin(), lower.end(), lower.begin(),
                   [](unsigned char c){ return std::tolower(c); });

    auto pos = lower.find("<et>");            // case-insensitive locate
    if (pos == std::string::npos) return {};

    std::string tail = content.substr(pos);
    std::regex re(R"(['"]([A-Za-z]{1,3})['"])"); // matches 'Cu' or "Cu"
    std::sregex_iterator it(tail.begin(), tail.end(), re), end;
    std::vector<std::string> elements;
    for (; it != end; ++it) elements.push_back((*it)[1].str());
    return elements;
}

Notes and heuristics: compile with a C++11 (or later) toolchain. Change the regex quantifier from {1,3} to {1,2} if only standard 1–2 letter symbols are expected. If multiple ET blocks may appear, loop with successive finds instead of returning after the first match. For very large files prefer scanning line-by-line and applying the regex only after the marker to avoid building a huge string in memory.

Troubleshooting: verify the file path and that the ifstream opened successfully; print the matched vector to confirm results; normalize symbol case if comparisons are needed (capitalize first letter, lowercase second). This complements ’s solution and addresses tag-case, multiple-block, and quoting variations that can trip simple equality checks.

Recommended Answers

All 2 Replies

Probably something like this (untested) code

#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;


int main()
{
    std::vector<std::string>  elementVector;
    std::ifstream in("filename.dat");
    std::string line;
    while( std::getline(in, line) )
    {
        if( line == "<et>" )
        {
            std::getline(in,line);
            stringstream st;
            st << line;
            std::string word;
            while( std::getline(st,word,'\'' ))
            {
                size_t pos = word.find('\'');
                if( pos != string::npos )
                    word.erase(pos,1);
                elementVector.push_back(word);
            }

        }
    }
}

Thanks a lot Ancient Dragon! This should do the job.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.