Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a line with integers and a string with spaces

Tags:

c++

string

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 ?

like image 536
Marijus Avatar asked Nov 19 '11 16:11

Marijus


3 Answers

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];
like image 98
Kerrek SB Avatar answered Oct 09 '22 21:10

Kerrek SB


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);
like image 1
perreal Avatar answered Oct 09 '22 19:10

perreal


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;
}
like image 1
Praetorian Avatar answered Oct 09 '22 21:10

Praetorian