C++ non null terminated char array outputting

后端 未结 5 585
刺人心
刺人心 2021-01-18 03:27

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

相关标签:
5条回答
  • 2021-01-18 03:46

    I see mainly two solutions.

    In case of ASCII data:

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

    then You'll always have clear null-terminated string in buffor.

    Second in case of ASCII data:

    std::string yourASCII(src,maxbytes);
    yourASCII.c_str() // would be null terminated.
    
    0 讨论(0)
  • 2021-01-18 03:47

    This works, but isn't safe against accidentally calling the standard char* version of 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 '\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
    
    0 讨论(0)
  • 2021-01-18 03:50

    A cheap solution would be to have a buffer that has space for an extra null character and just put a null character at the point when you know the actual size and then output the null-terminated buffer as you already do. Fast and reliable.

    0 讨论(0)
  • 2021-01-18 03:57

    If you don't care about the last byte, you can just

    buffer[buffersize-1] = 0;
    

    and then feed buffer to whatever string function you want. If it is shorter, everything will run to the null terminator that already exists, and if there was no terminator it will run to the one you just created.

    And it's fast :)

    0 讨论(0)
  • 2021-01-18 04:00

    If you want to put exactly maxbytes bytes, use write method

    stream.write(buffer, maxbytes);
    

    If you can have less bytes in buffer, how do you know how many of them your buffer contains? If '\0' marks buffer end, you can write:

    stream.write(buffer, std::find(buffer, buffer+maxbytes, '\0') - buffer);
    
    0 讨论(0)
提交回复
热议问题