Question on string

  • Thread starter Odysseas Gabrielides
  • Start date
P

peter koch

How can I use unsigned chars in a string object ?

The portable way is by specialising on unsigned char, and some
compilers allow you to define the default char as unsigned (although
this formally doesn't make it of type unsigned char). But most likely
you do not need this, so first tell us why you want your chars
unsigned.

/Peter
 
V

Vladyslav Lazarenko

The portable way is by specialising on unsigned char

typedef std::basic_string< unsigned char, std::char_traits<unsigned
int>, std::allocator<unsigned char> > ustring;

, and some
compilers allow you to define the default char as unsigned (although
this formally doesn't make it of type unsigned char).

Microsoft C++ compiler (/J option) - http://msdn.microsoft.com/en-us/library/0d294k5z(VS.80).aspx
GCC (-funsigned-char option) - http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/C-Dialect-Options.html
Others - http://www.google.com
 
V

Victor Bazarov

V

Vladyslav Lazarenko

Specializing what?

I guess basic_string and char_traits templates.
'Fraid not.  The standard only specifies char_traits specializations for
char and wchar_t.  There may not be any primary template definition.

You're right. GCC allows me to do typedef for that beast but nothing
else. I believe that it is possible to specialize char_traits for
unsigned char manually but it must be a huge job. I don't know why
somebody would need that.
 
V

Vladyslav Lazarenko

char_traits<unsigned int>?

Why not simply

    typedef std::basic_string<unsigned char> ustring;

?





V

My bad. Works either way.


#include <string>
#include <iostream>

//typedef std::basic_string<unsigned char, std::char_traits<unsigned
char>, std::allocator<unsigned char> > ustring; // Long path.
typedef std::basic_string<unsigned char> ustring; // Easy way.

int main() {
const unsigned char some_array[] = { 'H', 'E', 'L', 'L', 'O', 0 };
ustring s(some_array);

for (ustring::size_type i = 0, end_i = s.size(); i != end_i; ++i)
{
std::cout << s.at(i) << std::endl;
}

/*
std::cout << s << std::endl; // This won't work unless ostream
operator << defined for ustring...
*/
std::cout << s.c_str() << std::endl;
return s.size();
}
 
P

peter koch

Specializing what?
Yes. You should obviously specialise std::basic_string on unsigned
char. I doubt there is any other reasonable to understand that
statement?
'Fraid not.  The standard only specifies char_traits specializations for
char and wchar_t.  There may not be any primary template definition.

Yes - you might have to write your own traits class. Depending on what
you need, this might or might not be a problem.

/Peter
 
T

Thomas J. Gritzan

Odysseas said:
How can I use unsigned chars in a string object ?

If you need a kind of buffer of unsigned chars and these are not some
kind of characters, I suggest using std::vector<unsigned char> instead.

If you want to convert an unsigned char and put that into a string
object, then you need to clarify what you want exactly.
 
O

Odysseas Gabrielides

Odysseas said:
How can I use unsigned chars in a string object ?
To explain why I want to use unsigned chars:

I want to encode int and double with characters.
For exemple, to send via sockets the number 145. Instead of sending
'1','4' and '5' I thought of sending a string representing the number.
If I use char, the base will be 127. What do I mean ? I encode by doing:
buffer[0]=18 and buffer[1]=1. To decode the number, I do:
number+=buffer*pow(127,i)

Well I wanted to use unsigned char to be able to increase the numerical
base, and encode larger numbers (base with unsigned char -> 255 instead
of 127)

Exemple:

With 1 char I encode: 127*1 Total: 127 numbers

With 2 char I encode: 127*2 Total: 16129 numbers

With 3 char I encode: 127*3 Total: 2048383 numbers

With 1 unsigned char I encode: 255*1 Total: 255 numbers

With 2 unsigned char I encode: 127*2 Total: 65025 numbers

With 3 unsiged char I encode: 127*3 Total: 16581375 numbers

See the difference ?

So I was just wonderinf if I could use string objects or if I had to use
old char arrays to preparethe data for sending.
 
J

James Kanze

The portable way is by specialising on unsigned char,

Which is a lot of work, since you also have to provide a traits
class. (The standard doesn't require that a generic version of
std::char_traits exists, and the different compilers which do
provide it do so in incompatible ways.)

In practice, you can pretty much forget about there being a
template std::basic_string.
 
J

James Kanze

typedef std::basic_string< unsigned char, std::char_traits<unsigned
int>, std::allocator<unsigned char> > ustring;

Unspecified behavior. It may not compile, and if it does, it is
likely to have different behavior on different machines. (I
seem to recall someone trying it with g++ and VC++ in the French
speaking newsgroup, and getting different behavior.)

The only way to do this portably is something like:

class MyUnsignedCharTraits { /* ... */ } ;
typedef std::basic_string< unsigned char, MyUnsignedCharTraits >
UCString ;

If you want IO, etc. as well, you'll also have to implement a
lot of locale.
 
J

James Kanze

Not that huge. Five typedefs, fourteen simple (trivial?)
member functions.

Not that small, either. Note that you can probably get parts
of it by deriving from std::char_traits<char>. But what should
you do about things like std::char_traits<>::state_type?

And of course, if you're going to do any IO with it, you'll also
need a specialization for std::codecvt, and possibly other stuff
in locale.
 
P

peter koch

Odysseas said:
How can I use unsigned chars in a string object ?

To explain why I want to use unsigned chars:

I want to encode int and double with characters.
For exemple, to send via sockets the number 145. Instead of sending
'1','4' and '5' I thought of sending a string representing the number.
If I use char, the base will be 127. What do I mean ? I encode by doing:
buffer[0]=18 and buffer[1]=1. To decode the number, I do:
number+=buffer*pow(127,i)

Well I wanted to use unsigned char to be able to increase the numerical
base, and encode larger numbers (base with unsigned char -> 255 instead
of 127)

Exemple:

With 1 char I encode: 127*1 Total: 127 numbers

With 2 char I encode: 127*2 Total: 16129 numbers

With 3 char I encode: 127*3 Total: 2048383 numbers

With 1 unsigned char I encode: 255*1 Total: 255 numbers

With 2 unsigned char I encode: 127*2 Total: 65025 numbers

With 3 unsiged char I encode: 127*3 Total: 16581375 numbers

See the difference ?

So I was just wonderinf if I could use string objects or if I had to use
old char arrays to preparethe data for sending.


For the above you should use std::vector<unsigned char>.

/Peter
 

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
474,161
Messages
2,570,892
Members
47,426
Latest member
MrMet

Latest Threads

Top