0

I have the following example:

string name_data = "John:Green;96";

I need to parse the string name, the string surname and int data. I've tried using sscanf, but it isn't working!

How should I do this?

greedybuddha
  • 7,488
  • 3
  • 36
  • 50
user1779502
  • 573
  • 2
  • 8
  • 16

4 Answers4

1

You can use strtok() to first extract, the element that ends with :, and then the one that ends with ;. What remains will be the 96.

sscanf() is another option, although I don't consider it to be quite as flexible.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • Bad idea. `strtok()` is a pine becuase modifies the underlying string. C++ also has better options with the stream operator. – Martin York May 17 '13 at 03:49
  • I've successfully written all kinds of parsing code using `strtok()`, so your suggestion that it's a "pine" must be related to how you did it. Obviously, `strtok()` doesn't work for every single situation. But there was nothing about the description given originally that would preclude using `strtok()`. – Jonathan Wood May 17 '13 at 13:51
  • I am not sating you can't do it. You obviously can (you can write all your code in C; its possible but a pine :-). I am saying there are better techniques available with C++ and its bad idea as it mutates the underlying string. It also maintains internally global state which makes it annoying to use in multi threaded situations (but you can get around this by using [strtok_r](http://linux.die.net/man/3/strtok_r)) – Martin York May 17 '13 at 15:09
0

If you want to do it with sscanf, you can do it as follows:

string name_data = "John:Green;96";
char name_[256], surname_[256];
int data;
sscanf(name_data.c_str(), "%[^:]:%[^;];%d", name_, surname_, &data);
string name = name_, surname = surname_;

Note this assumes you'll only have up to 255 characters for name and surname, otherwise you'll need a bigger temporary buffer before converting it to string.

"%[^:]:%[^;];%d" means read a string until you find a ':', then skip that ':', then read a string until you find a ';', then skip that ';' and then read an integer

You can find additional functionalities/specifiers here.

i Code 4 Food
  • 2,144
  • 1
  • 15
  • 21
0

You can use stringstream to get your tokens. That program demonstrate how you can do that:

#include <sstream>
#include <iostream>
#include <string>

using namespace std;

int main() {
    string x = "John:Green;96";
    stringstream str(x);

    std::string  first;
    std::string  second;
    int          age;

    std::getline(str, first, ':');
    std::getline(str, second,';');
    str >> age;

    cout << "First: " << first << " Last: " << second << "  Age: " << age << endl;
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
Amadeus
  • 10,199
  • 3
  • 25
  • 31
0

Without using any secondary function calls other than that assoc. with the string class, we can do it like this:

size_t index = 0;
string firstName, surname, dataStr;
string tmpInput;
while (index!=name_data.length())
{
  // First identify the first name
  if (firstName.empty())
  {
    if (name_data[index] == ':')
    {
      firstName = tmpInput;
      tmpInput.clear();
    }
    else
      tmpInput.push_back(name_data[index]);
  }
  // Next identify the surname
  else if (surname.empty())
  {
    if (name_data[index] == ";")
    {
      surname = tmpInput;
      tmpInput.clear();
    }
    else 
      tmpInput.push_back(name_data[index]);
  }
  // Finally identify the integer as a string object
  else 
  {
    dataStr.push_back(name_data[index]);
  }
  index++;
}

To convert dataStr to an int would be just a simple atoi() call or use of the stringstream library.

d m
  • 581
  • 3
  • 6
  • 8