Вывод массива символов 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;

а затем передайте буфер любой Строковой функции, которую вы хотите. Если он короче, все будет работать до нулевого Терминатора что уже существует, а если бы не было Терминатора, он будет работать на тот, который вы только что создали.

и это быстро :)