Hello,

In the past I had written the following function to parse a string that was tab delimited:

void parseLine(string s)
{
        string fid, src, dst, cap_e, cap_f, fare_e, fare_f;
        istringstream isstream (s);

        getline(isstream,fid,'|');
        getline(isstream,src,'|');
        getline(isstream,dst,'|');
        getline(isstream,cap_e,'|');
        getline(isstream,cap_f,'|');
        getline(isstream,fare_e,'|');
        getline(isstream,fare_f,'|');
}

Now I need to parse a string where I dont know in advance how many fields are there. How can I do that as I dont know how long the string would be.

Example:

New Flight A33333
Action Takeoff 1230 Land 1430

I want to do something like -
If the first word is New then check the 3rd word
If the first word is Action and second word is takeoff then check the 3rd word for takeoff time and 5th word for landing time etc....

Thanks
-k

Dani AI

Generated

Good direction — is right that a dynamic container (vector) is the right way to handle an unknown number of fields. For space- or tab-separated commands like your examples, a concise way to get tokens is to stream-split into a vector:

std::istringstream iss(s);
std::vector<std::string> tokens{
  std::istream_iterator<std::string>{iss},
  std::istream_iterator<std::string>{}
};

Always validate before indexing. Use tokens.size() or tokens.at(i) so out-of-range accesses are caught. Normalize comparisons to avoid case problems:

std::string cmd = tokens.front();
std::transform(cmd.begin(), cmd.end(), cmd.begin(), ::tolower);
if (cmd == "new" && tokens.size() >= 3) {
  std::string flightId = tokens.at(2);
  // ...
}

For the flexible "Action Takeoff 1230 Land 1430" pattern, regular expressions let you extract times regardless of spacing or order:

std::regex re("takeoff\\s+(\\d{3,4}).*land\\s+(\\d{3,4})", std::regex_constants::icase);
std::smatch m;
if (std::regex_search(s, m, re)) {
  int t_takeoff = std::stoi(m[1].str()); // try/catch around stoi
  int hh = t_takeoff / 100, mm = t_takeoff % 100;
  // validate hh/mm
}

Practical tips: validate parsed numbers (minutes < 60, hours range), trim stray whitespace, handle quoted fields if names can contain spaces, and catch std::invalid_argument/std::out_of_range from stoi. Return a small parsed-struct or std::optional result and log parse errors so callers can react. If performance is critical, avoid regex and write a simple state machine to scan the string.

Recommended Answers

All 2 Replies

If you don't know how many strings, then use a std::vector<std::string> instead of named variables.

Something like

vector<string> fields;
string temp;
while ( getline(isstream,temp,'|') {
  fields.push_back(temp);
}

Then check fields[0] for whatever.

If you don't know how many strings, then use a std::vector<std::string> instead of named variables.

Something like

vector<string> fields;
string temp;
while ( getline(isstream,temp,'|') {
  fields.push_back(temp);
}

Then check fields[0] for whatever.

Thanks Salem. I will try that out

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.