string reading with sscanf

B

Bint

i have a string "success=1&u=0&name=bint&u=1&name=lucy&u=2&name=barry" etc

i can use sscanf(string,"success=%d", &d) to get the success value. but
after that i just want to read name and u pairs until there are no more. if
Iwere to do a
sscanf (string,"success=%d&u=%d&name=%s"), that would get me the values of
the first u/name, right? is there any way to retrieve the string pointer
position from sscanf so that I can just call it again from that point in the
string?

thanks
B
 
D

David Côme

i have a string "success=1&u=0&name=bint&u=1&name=lucy&u=2&name=barry"
etc

i can use sscanf(string,"success=%d", &d) to get the success value. but
after that i just want to read name and u pairs until there are no
more. if
Iwere to do a
sscanf (string,"success=%d&u=%d&name=%s"), that would get me the values
of
the first u/name, right? is there any way to retrieve the string pointer
position from sscanf so that I can just call it again from that point in
the
string?

thanks
B
use ostringstream and istringstream instead of sscanf.
 
B

Bint

I don't think my compiler has that. Is that part of standard C/C++? Is
there an include file for it?

Thanks
B


i have a string "success=1&u=0&name=bint&u=1&name=lucy&u=2&name=barry"
etc

i can use sscanf(string,"success=%d", &d) to get the success value. but
after that i just want to read name and u pairs until there are no more.
if
Iwere to do a
sscanf (string,"success=%d&u=%d&name=%s"), that would get me the values
of
the first u/name, right? is there any way to retrieve the string pointer
position from sscanf so that I can just call it again from that point in
the
string?

thanks
B
use ostringstream and istringstream instead of sscanf.
 
D

David Côme

I don't think my compiler has that. Is that part of standard C/C++? Is
there an include file for it?

Thanks
B



use ostringstream and istringstream instead of sscanf.

ostringstream and istringstream are standard classes of C++
PS: Don't reply at top.
 
B

Bint

ok thank you I got it. it's not clear right off how to use that do what I'm
trying to do though, i haven't really used streams at all
 
D

David Côme

ok thank you I got it. it's not clear right off how to use that do what
I'm
trying to do though, i haven't really used streams at all


Generaly use C++ tools when you can and C tools when you must.
So use std::string instead of array of char,stream instead of FILE* ....
 
J

James Kanze

use ostringstream and istringstream instead of sscanf.

I'm not sure that either are really appropriate here. If I've
understood him correctly, he's got a '&' separated list of
attribute value pairs. The easiest way of handling this is
probably something like my FieldArray classes; a first pass
which converts the string into a vector of strings, with one
attribute value pair in each element. Then split up the
elements into the attribute and the value (perhaps
std::transform with a conversion function---boost::regex could
probably help here).
 
D

Daniel T.

Bint said:
i have a string "success=1&u=0&name=bint&u=1&name=lucy&u=2&name=barry" etc

i can use sscanf(string,"success=%d", &d) to get the success value. but
after that i just want to read name and u pairs until there are no more. if
Iwere to do a
sscanf (string,"success=%d&u=%d&name=%s"), that would get me the values of
the first u/name, right? is there any way to retrieve the string pointer
position from sscanf so that I can just call it again from that point in the
string?

I would do something like this:


#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>

using namespace std;

istream& find( istream& is, char c )
{
find( istream_iterator<char>( is ), istream_iterator<char>(), c );
return is;
}

int main()
{
const char* str =
"success=1&u=0&name=bint&u=1&name=lucy&u=2&name=barry";

stringstream ss( str );
find( ss, '=' );
int i = 0;
ss >> i;
cout << "success = " << i << '\n';
int u;
string name;
while ( find( ss, '=' ) && ss >> u &&
find( ss, '=' ) && getline( ss, name, '&' ) )
{
cout << "u = " << u << " name = " << name << '\n';
}
}
 
A

aaragon

I would do something like this:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>

using namespace std;

istream& find( istream& is, char c )
{
find( istream_iterator<char>( is ), istream_iterator<char>(), c );
return is;

}

int main()
{
const char* str =
"success=1&u=0&name=bint&u=1&name=lucy&u=2&name=barry";

stringstream ss( str );
find( ss, '=' );
int i = 0;
ss >> i;
cout << "success = " << i << '\n';
int u;
string name;
while ( find( ss, '=' ) && ss >> u &&
find( ss, '=' ) && getline( ss, name, '&' ) )
{
cout << "u = " << u << " name = " << name << '\n';
}

}

I would use a tokenizer to do that. You can use the boost tokenizer
for that giving the token & or you can create your own by reading each
character and comparing it with '&' to separate the whole string in
tokens.
 
J

Jerry Coffin

i have a string "success=1&u=0&name=bint&u=1&name=lucy&u=2&name=barry" etc

i can use sscanf(string,"success=%d", &d) to get the success value. but
after that i just want to read name and u pairs until there are no more. if
Iwere to do a
sscanf (string,"success=%d&u=%d&name=%s"), that would get me the values of
the first u/name, right? is there any way to retrieve the string pointer
position from sscanf so that I can just call it again from that point in the
string?

You've gotten a couple of suggestions already, but I'll throw another
into the mix, just for fun:

// warning: only minimally tested. Makes no attempt at verifying or
// reacting reasonably to bad input.
#include <sstream>
#include <algorithm>
#include <map>
#include <iostream>
#include <string>
#include <stdlib.h>

// the real guts: read a single 'name=value' pair. Written as a template
// so the value can be an int, string, or anything else we can extract
// from a stream.
template<class T>
std::istream &getvalue(std::istream &is, T &value) {
// first read the whole 'name=value' pair
std::string temp;
std::getline(is, temp, '&');

// then find the value part:
int pos = temp.find('=');
std::string temp2(temp.substr(pos+1,-1));

// and read the value:
std::stringstream t(temp2);
t >> value;
return is;
}

typedef std::pair<int, std::string> uname;

// not technically allowed, but won't be found unless in std namespace:
namespace std {
std::istream &operator>>(std::istream &is, uname &un) {
getvalue(is, un.first);
getvalue(is, un.second);
return is;
}

std::eek:stream &operator<<(std::eek:stream &os, uname const &un) {
return os << un.first << ":\t" << un.second;
}
}

int main() {
std::stringstream input("success=1&u=0&name=bint"
"&u=1&name=lucy&u=2&name=barry");

std::map<int, std::string> values;

int success;
getvalue(input, success);

// read in the data
std::copy(std::istream_iterator<uname>(input),
std::istream_iterator<uname>(),
std::inserter(values, values.begin()));

// and display what we read:
std::copy(values.begin(), values.end(),
std::eek:stream_iterator<uname>(std::cout, "\n"));
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top