I've an input formatted like this:
integer multi-word-string integer
I know the maximum lenght of multi-word-string, however I don't know how many words it contains. How can I read it ?
I'd read the line first and convert the first and last word to integers. Loosely:
std::string line;
std::getline(infile, line);
size_t ofs_front = line.find(' ');
size_t ofs_back = line.rfind(' ');
int front = std::strtol(line.substr(0, ofs_front).c_str(), NULL, 0);
int back = std::strtol(line.substr(ofs_back).c_str(), NULL, 0);
std::string text = line.substr(ofs_front, ofs_back - ofs_front);
You'll have to do some modifications to get rid of spaces (e.g. increment the offsets to gobble up all spaces), and you should add lots of error checking.
If you want to normalize all the interior spaces inside the text, then there's another solution using string streams:
std::vector<std::string> tokens;
{
std::istringstream iss(line);
std::string token;
while (iss >> token) tokens.push_back(token);
}
// process tokens.front() and tokens.back() for the integers, as above
std::string text = tokens[1];
for (std::size_t i = 2; i + 1 < tokens.size(); ++i) text += " " + tokens[i];
Read the first integer. Jump to back of the string and skip digits. Then read an int from this point. The part in the middle is the string. May not be 100% correct but:
char buf[256], *t = buf, *p, str[256];
fread(buf, 1, 256, file);
int s,e;
t += sscanf(buf, "%d", &s);
*p = buf + strlen(buf);
while (isdigit(*p)) p--;
sscanf(p, "%d", &e);
strncpy(str, p, p - t);
This is not as efficient as @KerrekSB's solution, but another way to do this is to extract the first integer, then loop through the rest of the string until you find the second integer.
#include <iostream>
#include <sstream>
int main()
{
std::istringstream ss( "100 4 words to discard 200" );
int first, second;
char buf[1000] = {0};
if( !( ss >> first ) ) {
std::cout << "failed to read first int\n";
return 1;
}
while( !( ss >> second ) || !ss.eof() ) {
if( ss.eof() ) {
std::cout << "failed to read second int\n";
return 1;
}
ss.clear();
if( ss.getline( buf, 1000, ' ' ).bad() ) {
std::cout << "error extracting word\n";
return 1;
}
}
std::cout << "first = " << first << "\n";
std::cout << "second = " << second << "\n";
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With