I was trying to output a not null terminated char array to a file.
Actual thing is, I am receiving packets and then printing their fields.
Now as these field
This works, but isn't safe against accidentally calling the standard char*
version of operator<<
:
#include
template
std::ostream& operator<< ( std::ostream& out, const char ( & data ) [N] )
{
out.write ( data, N );
// or out.write ( data, strnlen ( data, N ) );
// if you want to stop at a '\0' in the data
return out;
}
struct Foo {
char one[5];
char two[1];
char three[5];
};
int main ( void )
{
using namespace std;
Foo foo = {
{ 'h', 'e', 'l', 'l', 'o' },
{ ' ' },
{'w', 'o', 'r', 'l', 'd'} };
cout << foo.one;
cout << foo.two;
cout << foo.three;
cout << endl;
}
This is safer, using a maxw
type which limits the length of the next char*
output:
struct maxw {
unsigned n;
maxw ( unsigned n ) : n ( n ) { }
};
struct maxw_stream {
std::ostream& stream;
unsigned n;
maxw_stream ( std::ostream& stream, unsigned n ) :
stream ( stream ),
n ( n ) {
}
};
maxw_stream operator<< ( std::ostream& out, const maxw& m )
{
return maxw_stream ( out, m.n );
}
std::ostream& operator<< ( const maxw_stream& out, const char* data )
{
out.stream.write ( data, strnlen ( data, out.n ) );
return out.stream;
}
// eg:
cout << maxw(4) << "Hello World!" << endl;
// Hell\n
cout << maxw(100) << "Hello World!" << endl;
// Hello World!\n