C++ не пустой завершенный вывод массива символов

Я не рекомендую делать это самостоятельно, если Вы не являетесь довольно опытными с блоком. Используя SSE, более, чем вероятный, потребует тщательной перестройки Ваших данных, как , Skizz указывает, и преимущество часто сомнительно в лучшем случае

для Вас, вероятно, было бы намного лучше записать очень маленькие циклы и сохранить Ваши данные очень плотно организованными и просто полагаться на компилятор, делающий это для Вас. И компилятор C Intel и GCC (начиная с 4.1) могут автовекторизовать Ваш код и вероятно сделают лучшее задание, чем Вы. (Просто добавьте - ftree-векторизуют к Вашему CXXFLAGS.)

Редактирование : Другая вещь, которую я должен упомянуть, состоит в том, что несколько компиляторов поддерживают блок intrinsics , который был бы, вероятно, IMO, быть легче использовать, чем asm () или __ asm {} синтаксис.

7
задан Graeme Perrow 10 October 2009 в 19:14
поделиться

5 ответов

Если вы хотите поместить ровно maxbytes байтов, используйте write метод

stream.write(buffer, maxbytes);

Если можете у вас меньше байтов в буфере, как узнать, сколько из них содержится в вашем буфере? Если '\ 0' отмечает конец буфера, вы можете написать:

stream.write(buffer, std::find(buffer, buffer+maxbytes, '\0') - buffer);
16
ответ дан 6 December 2019 в 08:15
поделиться

Дешевым решением было бы иметь буфер, в котором есть место для дополнительного нулевого символа, и просто помещать нулевой символ в точку, когда вы знаете фактический размер, а затем выводить нулевой -терминированный буфер, как вы это уже делаете. Быстро и надежно.

3
ответ дан 6 December 2019 в 08:15
поделиться

Это работает, но не t безопасен от случайного вызова стандартной char * версии оператора << :

#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 '\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;
}

Это безопаснее, если использовать тип 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
3
ответ дан 6 December 2019 в 08:15
поделиться

Я вижу в основном два решения.

В случае данных ASCII:

memset(dest,0,destlength); 
bytescopied = strncpy(dest, src, maxbytes);

, тогда у вас всегда будет чистый ноль -завершенная строка в буфере.

Второй в случае данных ASCII:

std::string yourASCII(src,maxbytes);
yourASCII.c_str() // would be null terminated.
0
ответ дан 6 December 2019 в 08:15
поделиться

Если вам не нужен последний байт, вы можете просто

buffer[buffersize-1] = 0;

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

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

0
ответ дан 6 December 2019 в 08:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: