Вывод массива символов C++ без null
Я пытался вывести не нулевой завершенный массив символов в файл.
на самом деле, я получаю пакеты, а затем печатаю их поля.
теперь, поскольку эти поля не являются null завершены, например, сегмент данных, который имеет размер 512, но может или не может быть полностью занят.
когда я пишу эти данные в файл, я использую простую
Итак, как я могу сказать выходной функции, чтобы написать только это много определенное количество байт?
вместо использования чего-то подобного, что дорого звонить каждый раз:
enter code here
bytescopied = strncpy(dest, src, maxbytes);
if (bytescopied < 0) { // indicates no bytes copied, parameter error
throw(fit); // error handler stuff here
} else if (bytescopied == maxbytes) {
dest[maxbytes-1] = ''; // force null terminator
}
5 ответов
если вы хотите поставить именно maxbytes
байт, используйте write
метод
stream.write(buffer, maxbytes);
если вы можете иметь меньше байтов в буфере, как вы знаете, сколько из них содержит ваш буфер? Если ''
отмечает конец буфера, вы можете написать:
stream.write(buffer, std::find(buffer, buffer+maxbytes, '') - buffer);
дешевым решением было бы иметь буфер, который имеет пространство для дополнительного нулевого символа и просто помещает нулевой символ в точку, когда вы знаете фактический размер, а затем выводите буфер с нулевым завершением, как вы уже это делаете. Быстро и надежно.
это работает, но не безопасно от случайного вызова стандарта char*
версия operator<<
:
#include <iostream>
template <unsigned N>
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 '' 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;
}
это безопаснее, используя maxw
тип, который ограничивает длину следующего char*
выход:
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
Я вижу в основном два решения.
в случае данных ASCII:
memset(dest,0,destlength);
bytescopied = strncpy(dest, src, maxbytes);
тогда у вас всегда будет четкая строка с нулевым завершением в buffor.
второй в случае данных ASCII:
std::string yourASCII(src,maxbytes);
yourASCII.c_str() // would be null terminated.
Если вы не заботитесь о последнем байте, вы можете просто
buffer[buffersize-1] = 0;
а затем передайте буфер любой Строковой функции, которую вы хотите. Если он короче, все будет работать до нулевого Терминатора что уже существует, а если бы не было Терминатора, он будет работать на тот, который вы только что создали.
и это быстро :)